MySQL - Почему этот медленно выполняющийся запрос не использует (как кажется) правильный индекс? - PullRequest
2 голосов
/ 30 мая 2019

Этот запрос работает и выполняет то, что я хочу, но он работает очень медленно. У нас есть таблица транзакций, которая содержит сумму, идентификатор пользователя, идентификатор партнера и описание. Когда у пользователя есть 3 из определенной транзакции, он получает одноразовый бонус.

SELECT t.str_spid, count(*) AS C
  FROM transactions t
  LEFT JOIN transactions AS x
    ON t.str_spid = x.str_spid
   AND x.str_prid = 148
   AND x.str_amount = 2500
 WHERE t.str_prid = 148
   AND (t.str_desc = "Annual Rewards" OR t.str_desc = "Annual Rewards (PRO)")
   AND t.str_amount = 2000
   AND x.str_spid IS NULL
 GROUP BY t.STR_SPID 
HAVING C = 3
 LIMIT 0,100;

У меня есть индексы для отдельных полей, а затем составные индексы следующим образом:

SPID_DE_PRID: STR_SPID, STR_DESC, STR_PRID
SPID_DE_PRID_AMT: STR_SPID, STR_AMOUNT, STR_DESC, STR_PRID

Когда я использую объяснение, я получаю возможные ключи (на t):

STR_SPID,STR_PRID,STRAMT,STRDESC,SPID_PRID,SPID_DE_PRID,SPID_DE_PRID_AMT

И используемый ключ: STR_PRID

На х я получаю:

STR_SPID,SPT_SOID,STRAMT,SPID_PRID,SPID_DE_PRID,SPID_DE_PRID_AMT

И используемый ключ: STR_SPID

Есть ли лучший индекс или способ переписать это, чтобы он работал быстрее?

1 Ответ

1 голос
/ 30 мая 2019

Вы ищете t для конкретных значений в str_prid и str_desc, поэтому это должны быть первые два столбца индекса, но у вас нет такого индекса.

Оптимизаторделает все возможное с индексом в одну колонку на str_prid, чтобы сузить поиск.

Если бы у вас был индекс на (str_prid, str_amount, str_desc, str_spid), я бы ожидал, что лучшая оптимизация для t будет наилучшей.

Тогда для x вы захотите найти соответствующие строки, поэтому вы захотите и индексировать (str_spid, str_prid, str_amount).

...