diff --git a/internal_packages/draft-list/lib/draft-list-store.coffee b/internal_packages/draft-list/lib/draft-list-store.coffee index 0a3d27e2e..2970acf44 100644 --- a/internal_packages/draft-list/lib/draft-list-store.coffee +++ b/internal_packages/draft-list/lib/draft-list-store.coffee @@ -3,6 +3,7 @@ Rx = require 'rx-lite' _ = require 'underscore' {Message, OutboxStore, + AccountStore, MutableQueryResultSet, MutableQuerySubscription, ObservableListDataSource, @@ -35,9 +36,14 @@ class DraftListStore extends NylasStore query = DatabaseStore.findAll(Message) .include(Message.attributes.body) .order(Message.attributes.date.descending()) - .where(draft: true, accountId: mailboxPerspective.accountIds) + .where(draft: true) .page(0, 1) + # Adding a "account_id IN (a,b,c)" clause to our query can result in a full + # table scan. Don't add the where clause if we know we want results from all. + if mailboxPerspective.accountIds.length < AccountStore.accounts().length + query.where(accountId: mailboxPerspective.accountIds) + subscription = new MutableQuerySubscription(query, {emitResultSet: true}) $resultSet = Rx.Observable.fromNamedQuerySubscription('draft-list', subscription) $resultSet = Rx.Observable.combineLatest [ diff --git a/src/flux/models/message.coffee b/src/flux/models/message.coffee index bc8cc0d2b..0866f5737 100644 --- a/src/flux/models/message.coffee +++ b/src/flux/models/message.coffee @@ -157,10 +157,20 @@ class Message extends ModelWithMetadata @additionalSQLiteConfig: setup: -> - ['CREATE INDEX IF NOT EXISTS MessageListThreadIndex ON Message(thread_id, date ASC)', - 'CREATE INDEX IF NOT EXISTS MessageListDraftIndex ON Message(account_id, draft)', - 'CREATE UNIQUE INDEX IF NOT EXISTS MessageDraftIndex ON Message(client_id)', - 'CREATE UNIQUE INDEX IF NOT EXISTS MessageBodyIndex ON MessageBody(id)'] + [ + # For thread view + 'CREATE INDEX IF NOT EXISTS MessageListThreadIndex ON Message(thread_id, date ASC)', + + # For draft lookups + 'CREATE UNIQUE INDEX IF NOT EXISTS MessageDraftIndex ON Message(client_id)', + + # Partial indexes for draft + 'CREATE INDEX IF NOT EXISTS MessageListDraftIndex ON Message(account_id, date DESC) WHERE draft = 1', + 'CREATE INDEX IF NOT EXISTS MessageListUnifiedDraftIndex ON Message(date DESC) WHERE draft = 1', + + # MessageBody lookups + 'CREATE UNIQUE INDEX IF NOT EXISTS MessageBodyIndex ON MessageBody(id)' + ] constructor: -> super diff --git a/src/flux/models/thread.es6 b/src/flux/models/thread.es6 index 4b5d6c6ff..1b61055f8 100644 --- a/src/flux/models/thread.es6 +++ b/src/flux/models/thread.es6 @@ -113,16 +113,27 @@ class Thread extends ModelWithMetadata { static additionalSQLiteConfig = { setup: () => [ + // ThreadCounts 'CREATE TABLE IF NOT EXISTS `ThreadCounts` (`category_id` TEXT PRIMARY KEY, `unread` INTEGER, `total` INTEGER)', 'CREATE UNIQUE INDEX IF NOT EXISTS ThreadCountsIndex ON `ThreadCounts` (category_id DESC)', - 'CREATE INDEX IF NOT EXISTS ThreadContactDateIndex ON `ThreadContact`(last_message_received_timestamp DESC, value, id)', + // ThreadContact + 'CREATE INDEX IF NOT EXISTS ThreadContactDateIndex ON `ThreadContact` (last_message_received_timestamp DESC, value, id)', - 'CREATE INDEX IF NOT EXISTS ThreadDateIndex ON `Thread`(last_message_received_timestamp DESC, id)', - 'CREATE INDEX IF NOT EXISTS ThreadStarIndex ON Thread(account_id, starred)', + // ThreadCategory + 'CREATE INDEX IF NOT EXISTS ThreadListCategoryIndex ON `ThreadCategory` (last_message_received_timestamp DESC, value, in_all_mail, unread, id)', + 'CREATE INDEX IF NOT EXISTS ThreadListCategorySentIndex ON `ThreadCategory` (last_message_sent_timestamp DESC, value, in_all_mail, unread, id)', - 'CREATE INDEX IF NOT EXISTS ThreadListCategoryIndex ON `ThreadCategory`(last_message_received_timestamp DESC, value, in_all_mail, unread, id)', - 'CREATE INDEX IF NOT EXISTS ThreadListCategorySentIndex ON `ThreadCategory`(last_message_sent_timestamp DESC, value, in_all_mail, unread, id)', + // Thread: General index + 'CREATE INDEX IF NOT EXISTS ThreadDateIndex ON `Thread` (last_message_received_timestamp DESC)', + + // Thread: Partial indexes for specific views + 'CREATE INDEX IF NOT EXISTS ThreadUnreadIndex ON `Thread` (account_id, last_message_received_timestamp DESC) WHERE unread = 1 AND in_all_mail = 1', + 'CREATE INDEX IF NOT EXISTS ThreadUnifiedUnreadIndex ON `Thread` (last_message_received_timestamp DESC) WHERE unread = 1 AND in_all_mail = 1', + + 'DROP INDEX IF EXISTS `Thread`.ThreadStarIndex', + 'CREATE INDEX IF NOT EXISTS ThreadStarredIndex ON `Thread` (account_id, last_message_received_timestamp DESC) WHERE starred = 1 AND in_all_mail = 1', + 'CREATE INDEX IF NOT EXISTS ThreadUnifiedStarredIndex ON `Thread` (last_message_received_timestamp DESC) WHERE starred = 1 AND in_all_mail = 1', ], } diff --git a/src/mailbox-perspective.coffee b/src/mailbox-perspective.coffee index b9d0ef51f..02dfc765c 100644 --- a/src/mailbox-perspective.coffee +++ b/src/mailbox-perspective.coffee @@ -185,11 +185,15 @@ class StarredMailboxPerspective extends MailboxPerspective threads: => query = DatabaseStore.findAll(Thread).where([ - Thread.attributes.accountId.in(@accountIds), Thread.attributes.starred.equal(true), Thread.attributes.inAllMail.equal(true), ]).limit(0) + # Adding a "account_id IN (a,b,c)" clause to our query can result in a full + # table scan. Don't add the where clause if we know we want results from all. + if @accountIds.length < AccountStore.accounts().length + query.where(Thread.attributes.accountId.in(@accountIds)) + return new MutableQuerySubscription(query, {emitResultSet: true}) canReceiveThreadsFromAccountIds: =>