YapDatabase icon indicating copy to clipboard operation
YapDatabase copied to clipboard

can view options's isPersistent change make compaitable

Open zzzworm opened this issue 8 years ago • 5 comments

we have some problem when we use YapDatabaseViewOptions, first time we set the view's options options.isPersistent = NO; and we find when we register the view,it is very slow(the view may have thousands of items).By change the option to options.isPersistent = YES, it seems the register progress performance better, but there are some problems: the sqlite db sometime report bad log like: Cannot create 'enumerate_stmt': 1 no such table:

zzzworm avatar May 17 '16 03:05 zzzworm

There's a related FAQ that may answer many of your questions: Is registering a YapDatabaseView expensive?

when we register the view,it is very slow(the view may have thousands of items).

The performance hit here is coming from the view enumerating over every item in the database (in order to figure out which items it should include in the view). As mentioned in the FAQ item, one way to cut this initial performance hit down it to use YapDatabaseViewOptions.allowedCollections.

By change the option to options.isPersistent = YES, it seems the register progress performance better,

After the initial population of the view, a persistent view will definitely be a lot faster. That's because the performance hit comes from the initial population of the view. After that, the view can simply update itself alongside the rest of the database. A persistent view will only need to perform the initial population once. A non-persistent view will need to perform the initial population every-time its registered. E.g. every app launch. (See FAQ item for more info.)

but there are some problems: the sqlite db sometime report bad log like: Cannot create 'enumerate_stmt': 1 no such table:

This sounds like a bug. Although one I've never had reported before. Perhaps its from switching back and forth between persistent & non-persistent views. Can you let me know where this log statement is coming from so I can look into it more?

robbiehanson avatar May 18 '16 16:05 robbiehanson

It comes when the data in the collection(relative to the view) update(such as insert and remove),we use YapDatabaseViewOptions.allowedCollections for performance.It seems when the non-persistent change to persistent, it will try to update some metadata table.if the view can population if need, I think this change(between non-persistent and persistent) can make compatible.

zzzworm avatar May 19 '16 02:05 zzzworm

It seems when the non-persistent change to persistent, it will try to update some metadata table.

You're toggling the entire YapDatabaseView between persistent & non-persistent? I'm not sure I understand what you're saying. Can you clarify a bit more?

robbiehanson avatar May 19 '16 16:05 robbiehanson

Yes, we are toggling YapDatabaseView between persistent & non-persistent

zzzworm avatar May 20 '16 02:05 zzzworm

Just hit this issue on YapDatabase/SQLCipher (2.9.3).

For a long time we've had a view Foo, which was not persisted.

I'm not entirely sure why it wasn't persisted (previous developer) - none of the reasons for having a non-persistent view apply, and the relevant commit that introduced it makes a vague reference to something that sounds like an application cache-invalidation bug.

So anyway,

For a long time we had a View which was isPersisted = NO. I modified the view to be isPersisted = YES. Works fine on new clients But when launching pre-existing clients, the view fails to load and I see console error:

no such table: view_Foo_map

This seems to be the relevant backtrace:

screen shot 2017-07-10 at 1 23 37 pm

I believe this is happening because of this line in YapDatabaseViewTransaction:

...
@implementation YapDatabaseViewTransaction
...

- (void)removeAllRowids
{
	YDBLogAutoTrace();
	
        // BUG HERE?
        // This logic seems fishy. Sure the view is *now* persistent, but it wasn't before.
        // So maybe we shouldn't expect these tables to exist.
	if ([self isPersistentView])
	{
		sqlite3_stmt *mapStatement = [viewConnection mapTable_removeAllStatement];
		sqlite3_stmt *pageStatement = [viewConnection pageTable_removeAllStatement];
		
		if (mapStatement == NULL || pageStatement == NULL)
			return;
		
...

The work around was to rename the view.

michaelkirk avatar Jul 10 '17 18:07 michaelkirk