2013-07-29 5 views
-1

Возможный дубликат: How to select date from datetime column?Где datetime = дата без полного сканирования таблицы?

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

Я хочу сделать что-то вроде этого:

UPDATE records SET earnings=(SELECT SUM(rate) 
FROM leads 
WHERE records.user_id=leads.user_id 
    AND DATE(leads.datetime)=records.date) 

Обратите внимание на последнюю часть: DATE(leads.datetime)=records.date. Это делает именно то, что нужно, но нужно сканировать каждую строку. Некоторые пользователи имеют тысячи потенциальных клиентов, поэтому это может занять некоторое время.

Таблица leads имеет INDEX по адресу user_id, datetime.

Я знаю, что вы можете использовать интервальные функции и делать что-то вроде WHERE datetime BETWEEN date AND interval + days или что-то в этом роде.

Каков наиболее эффективный и точный способ сделать это?

ответ

2

Я не знаком с датой функций в MySQL, но попробуйте изменить его

UPDATE records SET earnings= 
    (SELECT SUM(rate) 
    FROM leads 
    WHERE records.user_id=leads.user_id 
    AND leads.datetime >= records.date 
    And leads.datetime < records.date [+ one day]) -- however you do that in MySQL 

Вы получаете полное сканирование таблицы, поскольку выражение DATE(leads.datetime) не Sargable. Это потому, что это функция, которая должна работать с значением, хранящимся в столбце таблицы, и которое также сохраняется в любом индексе в этом столбце. Значение функции, очевидно, не может быть предварительно вычислено и сохранено в любом индексе, а только фактическое значение столбца, поэтому ни один индексный поиск не может определить, какие строки будут после выполнения функции, выполняемой на них, соответствовать критериям, указанным в предикате предложения Where , Изменение выражения так, чтобы значение столбца было равно сам по себе с одной или с другой стороны оператора предложения where (знак равенства или что-то еще), позволяет искать значения столбцов в индексе на основе одного выражения ,

2

Вы можете попробовать это:

UPDATE records 
    SET earnings = (SELECT SUM(rate) 
        FROM leads 
        WHERE records.user_id=leads.user_id AND 
          leads.datetime >= records.date and 
          leads.datetime < date_add(records.date, interval 1 day) 
        ); 

Вам нужен индекс leads(user_id, datetime) для этой работы.

Смежные вопросы