Запрос не попадает в индекс - это правильные столбцы для индексации? - PullRequest
1 голос
/ 16 мая 2019

Следующий запрос к базе данных Postgres выполняется довольно медленно (4000 + мс):

EXPLAIN ANALYZE SELECT "sms".* FROM "sms" WHERE "sms"."From" = 'NUMBER1' AND "sms"."To" = 'NUMBER2' AND "sms"."SmsMessageSid" = 'UNIQUE_ID' ORDER BY "sms"."id" ASC LIMIT 1;

Когда я запускаю psql и анализирую запрос, это результат:

Limit  (cost=5045.12..5045.12 rows=1 width=609) (actual time=57.011..57.011 rows=0 loops=1)
   ->  Sort  (cost=5045.12..5045.12 rows=1 width=609) (actual time=57.009..57.009 rows=0 loops=1)
         Sort Key: id
         Sort Method: quicksort  Memory: 25kB
         ->  Bitmap Heap Scan on sms  (cost=46.02..5045.11 rows=1 width=609) (actual time=56.993..56.993 rows=0 loops=1)
               Recheck Cond: (("To")::text = 'NUMBER1'::text)
               Filter: ((("From")::text = 'NUMBER2'::text) AND (("SmsMessageSid")::text = 'UNIQUE_ID'::text))
               Rows Removed by Filter: 2501
               Heap Blocks: exact=1230
               ->  Bitmap Index Scan on "index_sms_on_To"  (cost=0.00..46.02 rows=2623 width=0) (actual time=0.345..0.345 rows=2566 loops=1)
                     Index Cond: (("To")::text = 'NUMBER1'::text)

Я создал индекс следующим образом:

add_index "sms", ["id", "From", "To", "SmsMessageSid"], name: "on_id_from_to_sms_message_sid"

Но метод анализа не влияет на индекс.Я включаю неправильные столбцы?

Ответы [ 2 ]

3 голосов
/ 16 мая 2019

id должен прийти последний . Как

add_index "sms", ["From", "To", "SmsMessageSid", "id"], name: "on_id_from_to_sms_message_sid"

Обычно: сначала равенство, потом диапазон. Связанный:

id по-прежнему следует добавлять, если в комбинации ("From", "To", "SmsMessageSid") мало строк. Таким образом, Postgres может выбрать первую строку в верхней части индекса напрямую - при сканировании индекса , а не при сканировании растрового индекса , как вы видите сейчас.

Связанный:

0 голосов
/ 16 мая 2019

Попробуйте удалить id из вашего индекса, т.е.

add_index "sms", ["From", "To", "SmsMessageSid"], name: "on_id_from_to_sms_message_sid"`

Согласно https://www.postgresql.org/docs/9.5/indexes-multicolumn.html:

Индекс B-дерева с несколькими столбцами может использоваться с условиями запроса, которые включают любое подмножество столбцов индекса, но индекс наиболее эффективен, когда существуют ограничения на ведущие (крайние левые) столбцы. Точное правило состоит в том, что ограничения на равенство в начальных столбцах плюс любые ограничения на неравенство в первом столбце, который не имеет ограничения на равенство, будут использоваться для ограничения части сканируемого индекса. Ограничения на столбцы справа от этих столбцов проверяются в индексе, поэтому они сохраняют посещения самой таблицы, но не уменьшают часть индекса, которая должна быть отсканирована. Например, учитывая индекс на (a, b, c) и условие запроса, ГДЕ a = 5 И b> = 42 И c <77, индекс должен быть отсканирован из первой записи с a = 5 и b = 42 до последней записи с a = 5. Записи индекса с c> = 77 будут пропущены, но их все равно придется сканировать. Этот индекс в принципе может быть использован для запросов, которые имеют ограничения на b и / или c без ограничения на a - но весь индекс должен быть отсканирован, поэтому в большинстве случаев планировщик предпочел бы последовательное сканирование таблицы по сравнению с использованием индекса .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...