2013-12-11 2 views
0

Это то, что у меня есть сейчас.Выбор MySQL не очень-очень медленный

SELECT distinct ClientID 
    FROM Table 
    WHERE PAmt = '' and ClientID not in 
     (select distinct ClientID from Table where PAmt != '') 
    ORDER BY ID ASC 

ClientID может быть внутри Таблицы более одного раза, а некоторые из них имеют значение PAmt, а некоторые нет. Я пытаюсь получить только клиентов, у которых никогда не было значения PAmt. Стол имеет около 12000 записи, и только 2700 являются уникальной ClientID-х

+0

У вас есть индексы на идентификаторе клиента и ID? –

+1

@Fractal: '! =' Не будет оптимизирован индексом B-Tree – zerkms

+1

эй. это только я или ваш и статья в значительной степени проверяет то же, что и первое? SELECT ClientID, где PAmt пуст, но не ClientID, где PAmt не пуст. –

ответ

3

Я думаю, что это может быть проще решить

SELECT 
    ClientID, 
    MAX(IF(PAmt='',0,1)) AS HasPAmt 
FROM `Table` 
GROUP BY ClientID 
HAVING HasPAmt=0 

Редактировать

Некоторые слова на Обосновании этого:

Подзапросы в MySQL - это beasty вещь: если набор результатов слишком велик (Original SQL) или переплетается с вождением запроса (@ DavidFleeman's), внутренний запрос зацикливается, то есть он повторяется для ev во-первых, строка запроса вождения. Это, конечно же, дает плохую производительность.

Итак, мы пытаемся переформулировать запрос таким образом, чтобы избежать цикла. Мое предложение работает, запустив только два запроса: первый (все до HAVING) создаст временную таблицу, которая отмечает каждый отдельный идентификатор клиента как имеющий хотя бы одну непустую PAmt (или нет), вторая выбирает только те строки temp table, помеченные как имеющие отсутствие, в конечный набор результатов.

+0

OMG вы спасли меня от белой ночи. Спасибо! Работает как шарм :) Теперь я знаю, как сделать это лучше. – user3092543

1

пытаются реорганизовать запрос на что-то вроде этого:

select clientID 
from Table 
group by clientID 
having max(length(PAmt)) == 0 

, конечно, вы должны добавить индекс (ClientId, PAmt)

, если этот запрос будет по-прежнему работать медленно, добавить колонку с предварительно рассчитанным длина, и заменить PAmt этой колонке

+0

Эта функция работает лучше, с той же скоростью 0,016 с и дает мне правильные результаты. 2115 и по решению Евгения Рика у меня было 2114, возможно, у меня там NULL или что-то в этом роде. – user3092543

0

Заберите подзапрос:

$clientIds = runQuery("select distinct ClientID from Table where PAmt != ''"); 
$clientIds = implode(",", $clientIds); 

runQuery("SELECT distinct ClientID 
FROM Table 
WHERE PAmt = '' and ClientID not in 
    ({$clientIds}) 
ORDER BY ID ASC") 

Я знаю, что это выглядит как MySQL должен сделать этот шаг оптимизации для вас, но это не так. Вы найдете, что ваш запрос примерно в 12000 раз быстрее, если вы выполняете запрос в виде отдельного запроса.

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