2010-10-15 3 views
0

Я делаю запрос из базы данных SQL. В таблице содержится более миллиона записей.Оператор SQL занимает 8 часов для запуска

Это мой оператор SQL. Для работы требуется 8 часов. У кого-нибудь есть идеи? Заранее спасибо.

Select 
    Count (userID) as DIBWIZHits, Sum (ssnCount) as SSNs 
From 
    tbl_hits10 
Where 
(appName='DIBwiz QMT' or 
    appName like 'DIBwiz-Full%' or 
    appName like 'DIBwiz-Abb%' or 
    appName like 'DIBwiz-Qual%') 
    -- or appName like 'DIBwiz%Open%' or appName like 'DIBwiz%Q%') 
and 
    lu_date between 
    convert (datetime, '2010-09-01 00:00:00', 102) and 
    convert (datetime, '2010-09-30 23:59:59', 102) 
AND 
(userID<>'888888' and 
    userID<>'999999' and 
    userID<>'777777' and 
    userID<>'666666' and 
) 
+3

Какая СУБД это? –

+1

Похоже, что SQL Server из 'convert (datetime, ..., 102)' бит? Что-то должно быть катастрофически неправильно с планом выполнения или конфигурацией. Ни в коем случае полное сканирование таблицы на миллион записей занимает 8 часов. –

+1

Этот запрос может быть уродливым, но не существует объединений или предложений GROUP BY, поэтому он не должен заметно замедляться, чем сканирование таблицы. И я не могу понять, что сканирование на таблице такого размера займет около 8 часов. Что-то странное в вашей конфигурации? Ваша таблица ужасно фрагментирована? Он хранится на RAID-массиве дискет? – zinglon

ответ

0

У вас есть индексы на вашем столе? Если нет, вы должны хотя бы добавить индекс в поле userID, не добавляйте индекс в поле appName, поскольку используете «как», это не будет иметь никакого эффекта.

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

+1

Ваш комментарий о 'LIKE', который не пользуется индексом, является ложным, по крайней мере, в SQL Server 2005. Как Энтони использует' LIKE' (т. Е. Подстановочный знак в конце), он принесет пользу. Следующая статья иллюстрирует это - достаточно легко попробовать себя в mgmt studio express (бесплатно). http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx – Matt

4

У меня есть несколько советов по оптимизации.

1) Вы абсолютно должны использовать регулярные выражения для поиска имени приложения.

2) Вы должны быть сравнения идентификатор_пользователя к списку, таких как «AND (идентификатор_пользователя не в (1, 2, 3, 4, 5))

3) Ваша таблица базы данных должна иметь индексы.

Каждый из них должен значительно повысить производительность.

+1

Если это SQL Server (разумное предположение с учетом функции 'convert'), то: 1. Определенно не , что будет намного медленнее. 2. Это не имеет никакого значения. 3. Да, это должно быть первое, что нужно проверить. –

1

Имея функции обращенного (DateTime, ...) в там, где пункт будет выполнять синтаксический анализ, что для каждой строки. Вы бы лучше объявить переменную типа DateTime установлен в результат CONVERT и использование этого. Кроме того, использование «IN» и «NOT IN» лучше, чем число <>. Наконец, LIK Операторы E с подстановочными знаками обычно медленнее точных операторов.

+3

CONVERT будет выполняться ровно один раз при построении плана запроса, так как он использует постоянные значения. (NOT) IN генерирует тот же план, что и ряд предложений AND. LIKE всегда будет тривиально медленнее просто потому, что он должен делать больше работы, но настоящая боль возникает из-за наличия подстановки в начале, что предотвращает использование индекса, чего нет в этом запросе. (Хотя я предполагаю, что appName может быть огромной колонкой TEXT, которая немного повлияет на его состояние «%% morestuff%»). – zinglon

0

У вас есть индекс на appName?

также рассмотреть вопрос о @ Detect-х предложение использовать userid not in (<coma_separated_values>)

1

Ну, что может быть очень конкретной платформы, но я хотел бы попробовать вручную разбить его на вложенных запросов в зависимости от того, какие индексы присутствуют. Например. (Упрощенный), при условии, что есть индекс на lu_date:

Select Count (userID) as DIBWIZHits, Sum (ssnCount) as SSNs 
From 
    (select * from tbl_hits10 
    where lu_date between 
     convert (datetime, '2010-09-01 00:00:00',  102) 
     and convert (datetime, '2010-09-30 23:59:59', 102) 
) z 
Where (appName like 'DIBwiz%') 
AND userID not in ('016266'....) 

IHTH

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