Нужна помощь в ускорении запроса (FROM_UNIXTIME) - PullRequest
1 голос
/ 24 марта 2020

У меня есть запрос, который требует использования FROM_UNIXTIME, и он занимает не менее 0,2-0,5 секунд, и мне нужно использовать тот же запрос с другим оператором where как минимум 10 раз на странице.

Здесь это запрос

FROM `Users`
WHERE `Referrer` = '220048'
AND FROM_UNIXTIME(JoinDate, '%Y-%m-%d') = CURDATE()
AND `IP` NOT IN('IP', 'IP', 'IP')
AND `RegisterIP` NOT IN('IP', 'IP', 'IP')
AND `IP` != ''
AND `RegisterIP` != ''

Как бы я изменил FROM_UNIXTIME, чтобы сделать то же самое, но быстрее (база данных содержит около 900K строк)

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 24 марта 2020

Try:

  1. index для JoinDate
  2. использовать что-то вроде JoinDate = TO_UNIXTIME (CURDATE ())

Теория заключается в том, что оптимизатор имеет только сделать преобразование один раз и использовать индекс.

0 голосов
/ 25 марта 2020
WHERE `Referrer` = '220048'
AND FROM_UNIXTIME(JoinDate, '%Y-%m-%d') = CURDATE()
AND `IP` NOT IN('IP', 'IP', 'IP')
AND `RegisterIP` NOT IN('IP', 'IP', 'IP')
AND `IP` != ''
AND `RegisterIP` != ''

WHERE `Referrer` = '220048'
  AND JoinDate = UNIX_TIMESTAMP(CURDATE())  -- assuming `JoinDate` is a DATE
  AND `IP` NOT IN('IP', 'IP', 'IP', '')
  AND `RegisterIP` NOT IN('IP', 'IP', 'IP', '')

и имеют

INDEX(Referrer, JoinDate)
0 голосов
/ 24 марта 2020

В общем случае вы можете облегчить задачу, если будете следовать простым правилам для предложения WHERE:

  • Не размещайте вызов функции в левой части сравнения. поэтому измените его следующим образом: JoinDate = UNIX_TIMESTAMP(CURDATE())
  • Поместите ваши детали, соединенные «И» в порядке, который используется в составном указателе. Просто, например, : если у вас есть KEY (JoinDate, Referrer), тогда начните предложение "where" с того же порядка полей: JoinDate = ... AND Referrer = ... Остальная часть Поле «где» может меняться, но начало очень важно.

В этом случае весьма вероятно, что механизм MySQL выберет эффективный план выполнения, используя индекс.

...