Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
glamis Member Откуда: Сообщений: 626 |
Есть таблица ~ 3150тыс.записей. Надо выбрать все записи за определенный период (месяц). Пишу такое условие: data in ('20130101','20130102','20130103','20130104','20130105','20130106','20130107','20130108','20130109','20130110', '20130111','20130112','20130113','20130114','20130115','20130116','20130117','20130118','20130119','20130120', '20130121','20130122','20130123','20130124','20130125','20130126','20130127','20130128','20130129','20130130','20130131') время выполнения 13:56 (111646 записей). Пробовал: data >= '20130101' and data <= '20130131' - не быстрее. существует индекс по полю дата - не уникальный, не кластеризованный Можно ли ускорить? Таблица содержит несколько полей типа text. По крайней мере 3 из них нужны для анализа. Мне нужны данные за год. |
18 сен 13, 09:44 [14852382] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104751 |
Вы знаете, что такое IN ? Это много-много data = '20130101' OR data = '.....' OR data = '...' OR ...
Поле то какого типа ?
- версия сервера - структура таблицы и индексов - текст запроса - план выполнения - статистика чтений |
||||||
18 сен 13, 09:47 [14852398] Ответить | Цитировать Сообщить модератору |
glamis Member Откуда: Сообщений: 626 |
Согласно плана - inner join
datetime
MSSQL 2000 ServicePack 4
см вложение
SELECT [BEG_END] ,[DATA] ,[ERROR] ,[ERRORNO] ,[FORMA] ,[FUNC] ,[ID] ,[ISPOLN] ,[KOD_REC] ,[KTO] ,[NEWFIELD] ,[NEXT_DAT] ,[NEXT_TIM] ,[OTVET] ,[OTVET_FLAG] ,[PRIORT] ,[PROBL] ,[TEXT] ,[sql_id] FROM [ASUP21].[dbo].[sql_zapr] where data in ('20130101','20130102','20130103','20130104','20130105','20130106','20130107','20130108','20130109','20130110', '20130111','20130112','20130113','20130114','20130115','20130116','20130117','20130118','20130119','20130120', '20130121','20130122','20130123','20130124','20130125','20130126','20130127','20130128','20130129','20130130','20130131') К сообщению приложен файл (структура sql_zapr.rpt - 13Kb) cкачать ![]() |
||||||||||
18 сен 13, 10:57 [14852898] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104751 |
inner join с чем ?
С некластерным индексом запрос на выборку всех полей должен быть очень селективным. Чтобы затраты на поиск по индексу с последующим обращеним к другим полям были дешевле простого сканирования Исходя из "Есть таблица ~ 3150тыс.записей. " т.е. 3 000 000 записей и "время выполнения 13:56 (111646 записей)." т.е. 100 000 записей, запрос достаточно селективный. Но у вас нет кластерного индекса. Поэтому непонятно, что за план выбрал сервер. Скорее всего просто сканирование таблицы |
||||
18 сен 13, 11:07 [14852981] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Осталось показать:
|
||||||||||
18 сен 13, 11:12 [14853031] Ответить | Цитировать Сообщить модератору |
Мистер Хенки Member Откуда: канализация Сообщений: 6615 |
glamis, попробуйте обновить статистику update statistics [ASUP21].[dbo].[sql_zapr] with fullscanи использовать второй способ поиска с диапазоном. |
18 сен 13, 11:13 [14853039] Ответить | Цитировать Сообщить модератору |
Slalom Member Откуда: Сообщений: 8 |
Попробуйте указать индекс явно - nolock, index=... Лучше использовать условие data >= '20130101' and data <= '20130131' или создать временную таблицу со значением дат и делать join, чем условие in. и такой вопрос - а обновление статистики/реиндексацию давно делали на данную таблицу? Просто у нас на таблице с более чем 30млн записей (сервер слабенький, MsSQl 2000) - запрос отрабатывает максимум за 8сек. |
18 сен 13, 11:22 [14853116] Ответить | Цитировать Сообщить модератору |
bamper78 Member Откуда: Сообщений: 120 |
glamis,WHERE MONTH(date) = 01 AND YEAR(date)=2013 |
18 сен 13, 13:06 [14853964] Ответить | Цитировать Сообщить модератору |
не учите плохому
Guest |
не учите плохому |
||
18 сен 13, 13:09 [14853990] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Это чтобы уж наверняка не использовать индекс? |
||
18 сен 13, 13:10 [14853994] Ответить | Цитировать Сообщить модератору |
KRS544 Member Откуда: Сообщений: 497 |
Это случайно не таблица статистики, где ID - identity и primary key? Если так можно получить ID на начало периода и на конец и выполнить выбору по кластерному индексу |
18 сен 13, 13:32 [14854166] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47063 |
WHERE data>='20130101' AND data<'20130201'и индекс по data сделать, разумеется |
||
18 сен 13, 14:01 [14854352] Ответить | Цитировать Сообщить модератору |
vi0 Member Откуда: Сообщений: 295 |
зачем так? |
||
18 сен 13, 14:09 [14854414] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47063 |
Такие даты нельзя же отбрасывать?! |
||||
18 сен 13, 14:14 [14854448] Ответить | Цитировать Сообщить модератору |
babaEGA Member Откуда: Москва Сообщений: 289 |
Может быть сделать таблицу с датами или временную таблицу, как писали выше. И джоинить. Не пробовали?SELECT f INTO #t FROM ( SELECT '20130101' f UNION ALL SELECT '20130102' UNION ALL SELECT '20130103' UNION ALL SELECT '20130104' /* и тд*/ ) t SELECT [BEG_END] ,[DATA] /* остальные поля*/ FROM [ASUP21].[dbo].[sql_zapr] t1 JOIN #t t2 ON t1.date=t.f |
18 сен 13, 14:29 [14854573] Ответить | Цитировать Сообщить модератору |
glamis Member Откуда: Сообщений: 626 |
Параллельно преобразовал In в куроср (31 запись) |
||
18 сен 13, 14:40 [14854624] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104751 |
Да что вы говорите. Вы в плане выполнения увидели курсор ? Или это ваш вольный перевод ? |
||||
18 сен 13, 14:44 [14854653] Ответить | Цитировать Сообщить модератору |
glamis Member Откуда: Сообщений: 626 |
Схема красивая, но исторически - это dbf-файл, который в один прекрасный момент преобразовали в sql-таблицу, заливали частями и с какого-то момента параллельно работали., поэтому при таком плане выбирает и кучу посторонних записей. |
||
18 сен 13, 15:33 [14855019] Ответить | Цитировать Сообщить модератору |
KRS544 Member Откуда: Сообщений: 497 |
Мы легких путей не ищем :) |
||||
18 сен 13, 16:00 [14855321] Ответить | Цитировать Сообщить модератору |
glamis Member Откуда: Сообщений: 626 |
Хорошо помогла такая конструкция: Select sql_id, data, kto, forma, [text] from [ASUP21].[dbo].[sql_zapr] inner join (select sql_id sql_tmp from [ASUP21].[dbo].[sql_zapr] where data >= '20130101' and data < '20130201') tmp on [ASUP21].[dbo].[sql_zapr].[sql_id] = sql_tmp время - 2:25 Очень существенное влияние оказывает каждое text-поле Спасибо всем. |
18 сен 13, 17:04 [14855822] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47063 |
glamis, а зачем во FROMе подзапрос? Не понял! Да и алиасы надо везде расставить. |
18 сен 13, 17:21 [14855926] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47063 |
Смотрю - а там, оказывается, в основном запросе и в подзапросе одна и та же таблица! Может, основной запрос ограничить датами, а подзапрос вообще не нужен? |
18 сен 13, 17:25 [14855952] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104751 |
Это вы в плане запроса увидели ?
Это тоже в плане ? или в статистике чтений ? |
||||
18 сен 13, 17:33 [14856012] Ответить | Цитировать Сообщить модератору |
glamis Member Откуда: Сообщений: 626 |
Glory, Iap Фишка в том, что выбор за один проход влечет за собой выбор text-полей, что существенно замедляет процесс, поэтому сначала выбираю sql_id, а потом inner join (оказалось быстрее where ... in...) по sql_id ~ опытные прогоны показали, что быстрее в 3 раза. Не могу тестировать часто, тк при тестах в рабочее время возникают проблемы при работе других user-ов. Glory, не совсем понимаю план, вернее схема понятна, не понятна информация в узлах. как бы разобраться. iap, опыт показывает, что зачастую очень производительно бывает сделать выборку, предварительно организовав промежуточную выборку из той-же таблицы: например мой же пример требует дополнительного анализа text-полей. Если этот анализ включаю в основной Select - мрак, если через промежуточный - анализ text-полей - 0сек. Такова статистика... |
19 сен 13, 21:50 [14861711] Ответить | Цитировать Сообщить модератору |
glamis Member Откуда: Сообщений: 626 |
KRS544, хорошая схема, готов даже переформировать таблицу, чтобы пересоздать ключевое поле. не знаю как сделать лучше. |
19 сен 13, 22:00 [14861743] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |