Modified: trunk/Source/WebCore/ChangeLog (256737 => 256738)
--- trunk/Source/WebCore/ChangeLog 2020-02-17 16:48:00 UTC (rev 256737)
+++ trunk/Source/WebCore/ChangeLog 2020-02-17 17:44:54 UTC (rev 256738)
@@ -1,3 +1,18 @@
+2020-02-17 Sihui Liu <[email protected]>
+
+ IndexedDB: index cursor iteration is slow when there are a lot of index records from different object stores
+ https://bugs.webkit.org/show_bug.cgi?id=207377
+ <rdar://problem/59288679>
+
+ Reviewed by Brady Eidson.
+
+ Make the Index of IndexRecords table include indexID since we always perform search with indexID.
+ This would let SQLite optimize the index statement in SQLiteCursor with Covering Index and fix the slowness.
+
+ * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+ (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsIndex):
+ (WebCore::IDBServer::v1IndexRecordsIndexSchema): Deleted.
+
2020-02-17 Zalan Bujtas <[email protected]>
[LFC] Remove ReplacedBox::m_layoutBox
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (256737 => 256738)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2020-02-17 16:48:00 UTC (rev 256737)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2020-02-17 17:44:54 UTC (rev 256738)
@@ -64,7 +64,7 @@
constexpr auto objectStoreInfoTableNameAlternate = "\"ObjectStoreInfo\""_s;
constexpr auto v2ObjectStoreInfoSchema = "CREATE TABLE ObjectStoreInfo (id INTEGER PRIMARY KEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, autoInc INTEGER NOT NULL ON CONFLICT FAIL)"_s;
constexpr auto v1IndexRecordsRecordIndexSchema = "CREATE INDEX IndexRecordsRecordIndex ON IndexRecords (objectStoreID, objectStoreRecordID)"_s;
-constexpr auto v2IndexRecordsIndexSchema = "CREATE INDEX IndexRecordsIndex ON IndexRecords (key, value)"_s;
+constexpr auto IndexRecordsIndexSchema = "CREATE INDEX IndexRecordsIndex ON IndexRecords (indexID, key, value)"_s;
// Current version of the metadata schema being used in the metadata database.
static const int currentMetadataVersion = 1;
@@ -195,12 +195,6 @@
return indexRecordsTableSchemaString;
}
-static const String& v1IndexRecordsIndexSchema()
-{
- static NeverDestroyed<WTF::String> indexRecordsIndexSchemaString("CREATE INDEX IndexRecordsIndex ON IndexRecords (key)");
- return indexRecordsIndexSchemaString;
-}
-
static const String blobRecordsTableSchema(const String& tableName)
{
return makeString("CREATE TABLE ", tableName, " (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)");
@@ -515,7 +509,7 @@
// If there is no IndexRecordsIndex index at all, create it and then bail.
if (sqliteResult == SQLITE_DONE) {
- if (!m_sqliteDB->executeCommand(v2IndexRecordsIndexSchema)) {
+ if (!m_sqliteDB->executeCommand(IndexRecordsIndexSchema)) {
LOG_ERROR("Could not create IndexRecordsIndex index in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return false;
}
@@ -534,11 +528,10 @@
ASSERT(!currentSchema.isEmpty());
// If the schema in the backing store is the current schema, we're done.
- if (currentSchema == v2IndexRecordsIndexSchema)
+ if (currentSchema == IndexRecordsIndexSchema)
return true;
- RELEASE_ASSERT(currentSchema == v1IndexRecordsIndexSchema());
-
+ // Otherwise, update the schema.
SQLiteTransaction transaction(*m_sqliteDB);
transaction.begin();
@@ -547,7 +540,7 @@
return false;
}
- if (!m_sqliteDB->executeCommand(v2IndexRecordsIndexSchema)) {
+ if (!m_sqliteDB->executeCommand(IndexRecordsIndexSchema)) {
LOG_ERROR("Could not create IndexRecordsIndex index in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return false;
}