Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Есть запрос

SELECT COUNT(*) CNT FROM
V1_EMARCH_MESSAGE 
LEFT JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120409 00:00:00'


Он отрабатывает практически мгновенно и выдает количество 72. В таблице примерно 125000 сообщений. На V1_EMARCH_SEARCH.MESSAGE_ID есть индекс и на MSG_DATE есть индекс. На SEARCH_CONTENT есть full text index.

Кроме полнотекстового поиска, в приложении есть опция точного поиска по like, которая однако работает только если другими критериями уже ограничен результат, т.е. сначала считается количество сообщений без like и если оно больше 500 выдается ворнинг и отлуп, если меньше то на эти 500 или меньше уже применяется like.

Так вот если я добавляю like

SELECT COUNT(*) CNT FROM
V1_EMARCH_MESSAGE 
LEFT JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120409 00:00:00'
AND SEARCH_CONTENT LIKE '%Ingram%'


То это длится несколько минут, т.е. он видимо гонит сравнение like по всем 125000 записям, хотя мог бы отфильтровать эти 72 по дате и натравить like только на них.

Я немного переписал запрос с подзапросом, однако это не помогает

select count(*) CNT FROM
(
SELECT SEARCH_CONTENT FROM V1_EMARCH_MESSAGE 
LEFT JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120409 00:00:00'
) MSG
WHERE SEARCH_CONTENT LIKE '%Ingram%'


Последнее мне совершенно не понятно, почему и в этом случае запрос длится минуты. Подзапрос взовращает веть только 72 записи и like по ним должен отработать быстро. Если я помещаю их во временную таблицу и затем делаю поиск по like отрабатывает почти мгновенно.

Можно конечно ограничиться решением с временной таблицей, но хочется разобраться.
5 апр 12, 14:49    [12370659]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Ну, посмотрите планы. А не может, скорее всего, потому что не нострадамус, чтобы угадывать, насколько селективно условие SEARCH_CONTENT LIKE '%Ingram%'.
5 апр 12, 14:54    [12370690]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
А в последнем случае почему? Оптимайзер трасформирует запрос в прежний который длится минуты?
5 апр 12, 15:04    [12370784]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Пуп
А в последнем случае почему? Оптимайзер трасформирует запрос в прежний который длится минуты?
Планы. Планы смотрите.
5 апр 12, 15:06    [12370794]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Гавриленко Сергей Алексеевич,

Я не совсем понимаю план, можете помочь истолковать?

К сообщению приложен файл. Размер - 85Kb
5 апр 12, 15:13    [12370839]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
Пуп
Есть запрос
Запрос именно такой, с датой в виде константы? Или там переменная?
5 апр 12, 15:14    [12370848]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
alexeyvg
Пуп
Есть запрос
Запрос именно такой, с датой в виде константы? Или там переменная?


Из приложения связанная переменная, в management studio для тестирования тупо текстом написал в виде константы. Это большой роли не играет. Без like выполняется мгновенно
5 апр 12, 15:19    [12370895]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
на другом серваке план такого же запроса таков

К сообщению приложен файл. Размер - 95Kb
5 апр 12, 15:19    [12370897]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
iljy
Member

Откуда:
Сообщений: 8711
Пуп,

во-первых - выкладывайте реальные планы в виде sqlplan.
Во-вторых - замена переменной на константу может ОЧЕНЬ сильно повлиять на план.
5 апр 12, 15:24    [12370933]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
+
CNT
-----------
11

(1 row(s) affected)

Rows                 Executes             StmtText                                                                                                                                                                                                                                                StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument                                                                                                                                                                                            DefinedValues                                                                                       EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList                                                                                          Warnings Type                                                             Parallel EstimateExecutions
-------------------- -------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- ------------- ------------- ------------- ----------- ---------------- --------------------------------------------------------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
1                    1                    select count(*) CNT FROM
(
SELECT SEARCH_CONTENT FROM V1_EMARCH_MESSAGE 
LEFT JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120401 00:00:00'
) MSG
WHERE SEARCH_CONTENT LIKE '%Purchase%'    1           1           0           NULL                           NULL                           NULL                                                                                                                                                                                                NULL                                                                                                1             NULL          NULL          NULL        1,774266         NULL                                                                                                NULL     SELECT                                                           0        NULL
0                    0                      |--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1009],0)))                                                                                                                                                                             1           2           1           Compute Scalar                 Compute Scalar                 DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1009],0))                                                                                                                                              [Expr1006]=CONVERT_IMPLICIT(int,[Expr1009],0)                                                       1             0             0,0002167284  11          1,774266         [Expr1006]                                                                                          NULL     PLAN_ROW                                                         0        1
1                    1                           |--Stream Aggregate(DEFINE:([Expr1009]=Count(*)))                                                                                                                                                                                                1           3           2           Stream Aggregate               Aggregate                      NULL                                                                                                                                                                                                [Expr1009]=Count(*)                                                                                 1             0             0,0002167284  11          1,774266         [Expr1009]                                                                                          NULL     PLAN_ROW                                                         0        1
11                   1                                |--Hash Match(Inner Join, HASH:([dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID])=([dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]), RESIDUAL:([dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID]=[dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]))               1           4           3           Hash Match                     Inner Join                     HASH:([dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID])=([dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]), RESIDUAL:([dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID]=[dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID])  NULL                                                                                                360,3807      0             0,0342506     9           1,77405          NULL                                                                                                NULL     PLAN_ROW                                                         0        1
4070                 1                                     |--Filter(WHERE:([dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT] like '%Purchase%'))                                                                                                                                                1           5           4           Filter                         Filter                         WHERE:([dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT] like '%Purchase%')                                                                                                                        NULL                                                                                                504,3289      0             0,2830617     11          1,732763         [dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID]                                                      NULL     PLAN_ROW                                                         0        1
321671               1                                     |    |--Clustered Index Scan(OBJECT:([dbtest].[dbo].[V1_EMARCH_SEARCH].[V1_EMARCH_SEARCH_PK]))                                                                                                                                         1           6           5           Clustered Index Scan           Clustered Index Scan           OBJECT:([dbtest].[dbo].[V1_EMARCH_SEARCH].[V1_EMARCH_SEARCH_PK])                                                                                                                                    [dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID], [dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT]  321661        1,095718      0,3539841     67          1,449702         [dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID], [dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT]  NULL     PLAN_ROW                                                         0        1
1404                 1                                     |--Index Seek(OBJECT:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[V1_EMARCH_MSG_MDT_IDX]), SEEK:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[MSG_DATE] >= '2012-04-01 00:00:00.000') ORDERED FORWARD)                                                  1           8           4           Index Seek                     Index Seek                     OBJECT:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[V1_EMARCH_MSG_MDT_IDX]), SEEK:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[MSG_DATE] >= '2012-04-01 00:00:00.000') ORDERED FORWARD                              [dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]                                                             1389,543      0,005347222   0,001685498   11          0,00703272       [dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]                                                             NULL     PLAN_ROW                                                         0        1

(7 row(s) affected)


Длилось это 20 минут. Если убрать like то меньше секунды.
5 апр 12, 16:39    [12371592]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Ну так по MSG_DATE есть индекс V1_EMARCH_MSG_MDT_IDX
А для SEARCH_CONTENT LIKE '%Purchase%' приходится сканировать всю таблицу.
5 апр 12, 16:46    [12371665]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Glory
Ну так по MSG_DATE есть индекс V1_EMARCH_MSG_MDT_IDX
А для SEARCH_CONTENT LIKE '%Purchase%' приходится сканировать всю таблицу.


Это я понимаю, только не понимаю почему он здесь

select count(*) CNT FROM
(
SELECT SEARCH_CONTENT FROM V1_EMARCH_MESSAGE 
LEFT JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120409 00:00:00'
) MSG
WHERE SEARCH_CONTENT LIKE '%Ingram%'


Сначала не выбирает эти несколько записей по дате. Без LIKE он это делает менее секунды, и только потом уже к этим не применяет like? Веть я даже подзапрос сделал специально. Веть подзапрос

(
SELECT SEARCH_CONTENT FROM V1_EMARCH_MESSAGE 
LEFT JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120409 00:00:00'
) MSG


должен отработать первым и вернуть эти несколько десятков строк и потом уже клишь к ним применить LIKE. Почему он этого не делает?
5 апр 12, 16:49    [12371692]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Пуп
Без LIKE он это делает менее секунды, и только потом уже к этим не применяет like? Веть я даже подзапрос сделал специально. Веть подзапрос

Потому что оптмизируется весь текст запроса, а не частями
Кроме того у вас соединение таблиц. А критерии фильтрации относятся к разным таблицам

Попробуйте поставить LEFT OUTER LOOP JOIN
5 апр 12, 16:52    [12371715]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Glory,

есть! Теперь работает как надо! И LIKE срабатывает уже после.

+
CNT
-----------
11

(1 row(s) affected)

Rows                 Executes             StmtText                                                                                                                                                                                                                                                         StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument                                                                                                                                                                          DefinedValues                                       EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList                                          Warnings Type                                                             Parallel EstimateExecutions
-------------------- -------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------- ------------- ------------- ------------- ----------- ---------------- --------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
1                    1                    select count(*) CNT FROM
(
SELECT SEARCH_CONTENT FROM V1_EMARCH_MESSAGE 
LEFT OUTER LOOP JOIN V1_EMARCH_SEARCH ON (V1_EMARCH_MESSAGE.ID = V1_EMARCH_SEARCH.MESSAGE_ID)
WHERE MSG_DATE >= '20120401 00:00:00'
) MSG
WHERE SEARCH_CONTENT LIKE '%Purchase%'  1           1           0           NULL                           NULL                           NULL                                                                                                                                                                              NULL                                                1             NULL          NULL          NULL        4,605039         NULL                                                NULL     SELECT                                                           0        NULL
0                    0                      |--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1011],0)))                                                                                                                                                                                      1           2           1           Compute Scalar                 Compute Scalar                 DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1011],0))                                                                                                                            [Expr1006]=CONVERT_IMPLICIT(int,[Expr1011],0)       1             0             0,0002167479  11          4,605039         [Expr1006]                                          NULL     PLAN_ROW                                                         0        1
1                    1                           |--Stream Aggregate(DEFINE:([Expr1011]=Count(*)))                                                                                                                                                                                                         1           3           2           Stream Aggregate               Aggregate                      NULL                                                                                                                                                                              [Expr1011]=Count(*)                                 1             0             0,0002167479  11          4,605039         [Expr1011]                                          NULL     PLAN_ROW                                                         0        1
11                   1                                |--Filter(WHERE:([dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT] like '%Purchase%'))                                                                                                                                                              1           4           3           Filter                         Filter                         WHERE:([dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT] like '%Purchase%')                                                                                                      NULL                                                360,4132      0             0,001065781   9           4,604823         NULL                                                NULL     PLAN_ROW                                                         0        1
1417                 1                                     |--Nested Loops(Inner Join, OUTER REFERENCES:([dbtest].[dbo].[V1_EMARCH_SEARCH].[ID], [Expr1010]) WITH UNORDERED PREFETCH)                                                                                                                      1           5           4           Nested Loops                   Inner Join                     OUTER REFERENCES:([dbtest].[dbo].[V1_EMARCH_SEARCH].[ID], [Expr1010]) WITH UNORDERED PREFETCH                                                                                     NULL                                                1211,115      0             0,005062459   63          4,603757         [dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT]  NULL     PLAN_ROW                                                         0        1
1417                 1                                          |--Nested Loops(Inner Join, OUTER REFERENCES:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID], [Expr1009]) WITH UNORDERED PREFETCH)                                                                                                                1           7           5           Nested Loops                   Inner Join                     OUTER REFERENCES:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID], [Expr1009]) WITH UNORDERED PREFETCH                                                                                    NULL                                                1211,115      0             0,005808743   11          1,825927         [dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]              NULL     PLAN_ROW                                                         0        1
1417                 1                                          |    |--Index Seek(OBJECT:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[V1_EMARCH_MSG_MDT_IDX]), SEEK:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[MSG_DATE] >= '2012-04-01 00:00:00.000') ORDERED FORWARD)                                                 1           9           7           Index Seek                     Index Seek                     OBJECT:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[V1_EMARCH_MSG_MDT_IDX]), SEEK:([dbtest].[dbo].[V1_EMARCH_MESSAGE].[MSG_DATE] >= '2012-04-01 00:00:00.000') ORDERED FORWARD            [dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]             1389,651      0,005347222   0,001685617   11          0,007032839      [dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]             NULL     PLAN_ROW                                                         0        1
1417                 1417                                       |    |--Index Seek(OBJECT:([dbtest].[dbo].[V1_EMARCH_SEARCH].[V1_EMARCH_SEARCH_MID]), SEEK:([dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID]=[dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]) ORDERED FORWARD)                                       1           10          7           Index Seek                     Index Seek                     OBJECT:([dbtest].[dbo].[V1_EMARCH_SEARCH].[V1_EMARCH_SEARCH_MID]), SEEK:([dbtest].[dbo].[V1_EMARCH_SEARCH].[MESSAGE_ID]=[dbtest].[dbo].[V1_EMARCH_MESSAGE].[ID]) ORDERED FORWARD  [dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]              1             0,003125      0,0001581     11          1,813085         [dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]              NULL     PLAN_ROW                                                         0        1389,651
1417                 1417                                       |--Clustered Index Seek(OBJECT:([dbtest].[dbo].[V1_EMARCH_SEARCH].[V1_EMARCH_SEARCH_PK]), SEEK:([dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]=[dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]) LOOKUP ORDERED FORWARD)                                     1           12          5           Clustered Index Seek           Clustered Index Seek           OBJECT:([dbtest].[dbo].[V1_EMARCH_SEARCH].[V1_EMARCH_SEARCH_PK]), SEEK:([dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]=[dbtest].[dbo].[V1_EMARCH_SEARCH].[ID]) LOOKUP ORDERED FORWARD     [dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT]  1             0,003125      0,0001581     63          2,772768         [dbtest].[dbo].[V1_EMARCH_SEARCH].[SEARCH_CONTENT]  NULL     PLAN_ROW                                                         0        1211,115

(9 row(s) affected)


Спасибо, Глори! А можете объяснить почему заработало с LOOP?
5 апр 12, 17:12    [12371812]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Пуп
А можете объяснить почему заработало с LOOP?

Потому что план поменялся
5 апр 12, 17:15    [12371827]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Glory
Пуп
А можете объяснить почему заработало с LOOP?

Потому что план поменялся


:)

Это то понятно, что поменялся, но почему он поменялся в лучшую сторону, что именно директива LOOP заставила делать по другому?
5 апр 12, 17:19    [12371852]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Одна стратегия соединения поменялась на другую
Hash Match на Nested Loops
5 апр 12, 17:23    [12371883]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Glory
Одна стратегия соединения поменялась на другую
Hash Match на Nested Loops


Хм. И это косвенно повлияло, что лучше сначала сджойнить и отфильтровать по дате и только потом уже применить like? Веть сам способ соедиения join'a не так важен в данном случае, как тот факт что сначала можно отфильтровать по дате и только потом применить like.
5 апр 12, 17:28    [12371929]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Пуп
Веть сам способ соедиения join'a не так важен в данном случае, как тот факт что сначала можно отфильтровать по дате и только потом применить like.

В вашем индексе по дате НЕТ информации о поле SEARCH_CONTENT
Что сервер будет фильтровать по-вашему ?
5 апр 12, 17:35    [12371987]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Glory
Пуп
Веть сам способ соедиения join'a не так важен в данном случае, как тот факт что сначала можно отфильтровать по дате и только потом применить like.

В вашем индексе по дате НЕТ информации о поле SEARCH_CONTENT
Что сервер будет фильтровать по-вашему ?


Я ожидал что он сначала отфильтрует подмножество строк из V1_EMARCH_MESSAGE удовлетворяющих условию MSG_DATE >= '20120409 00:00:00'. Далее он сделает джойн с V1_EMARCH_SEARCH. И уже потом применит like.

Если бы я был оптимайзером, я бы поступил именно так! :)
5 апр 12, 17:42    [12372046]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Пуп
Далее он сделает джойн с V1_EMARCH_SEARCH.

Вот расшифруйте это. Как это выглядит в вашем понимании.

Начальные условия - у вас непроделенное число записей из V1_EMARCH_MESSAGE

Сообщение было отредактировано: 5 апр 12, 17:44
5 апр 12, 17:43    [12372059]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Пуп
Member

Откуда:
Сообщений: 386
Glory
Пуп
Далее он сделает джойн с V1_EMARCH_SEARCH.

Вот расшифруйте это. Как это выглядит в вашем понимании.

Начальные условия - у вас непроделенное число записей из V1_EMARCH_MESSAGE


Ну и что что непроделенное число записей. Все равно условие MSG_DATE >= '20120409 00:00:00' их количество не увеличит, а только уменьшит или оставит прежним. Рассуждаем далее. Если делать джойн до этого условия то джойтить придется полюбому все строки таблицы V1_EMARCH_MESSAGE. Если после, то либо так же все, либо какое то меньшее количество. Так что второй случай по любому выгоднее, либо эффект тот же либо выигрыш от предварительно отброшенных условием строк и небоходимость джойнить меньше строк.
5 апр 12, 17:59    [12372181]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
Пуп
Glory
пропущено...

Вот расшифруйте это. Как это выглядит в вашем понимании.

Начальные условия - у вас непроделенное число записей из V1_EMARCH_MESSAGE


Ну и что что непроделенное число записей. Все равно условие MSG_DATE >= '20120409 00:00:00' их количество не увеличит, а только уменьшит или оставит прежним. Рассуждаем далее. Если делать джойн до этого условия то джойтить придется полюбому все строки таблицы V1_EMARCH_MESSAGE. Если после, то либо так же все, либо какое то меньшее количество. Так что второй случай по любому выгоднее, либо эффект тот же либо выигрыш от предварительно отброшенных условием строк и небоходимость джойнить меньше строк.
Ну, просто оптимизатор ошибся. Если бы количество записей после фильтра MSG_DATE >= '20120409 00:00:00' было бы больше, то выгоднее было бы не делать поиск, а потом лукап и фильтр, а сразу сканировать таблицу, избежав лукапа.

То есть просто сервер ошибся в определении селективности первого условия.

Можно попробовать обновить статистику по этой таблице и выполнить первоначальный запрос ещё раз. В принципе это более правильно, чем такие хинты типа inner loop join, потому что при другом значении даты ситуация может поменяться.
5 апр 12, 19:11    [12372581]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
Пуп
Если делать джойн до этого условия то джойтить придется полюбому все строки таблицы V1_EMARCH_MESSAGE.

Джойн - это всего лишь название _логической_ операции
Физические же действия могут быть разными. Потому что есть как минимум 3 стратегии джойнов.
Вот ваш индекс V1_EMARCH_SEARCH.MESSAGE_ID неуникальный, поле SEARCH_CONTENT не содержит.
В вашем случае циклы с поисками оказались выгоднее. Но это не значит, что они будут выгодными всегда, при любом количестве записей.
5 апр 12, 19:34    [12372690]     Ответить | Цитировать Сообщить модератору
 Re: Почему оптимайзер не срабатывает в следующем запросе  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3752
Glory
Пуп
Если делать джойн до этого условия то джойтить придется полюбому все строки таблицы V1_EMARCH_MESSAGE.

Джойн - это всего лишь название _логической_ операции
Физические же действия могут быть разными. Потому что есть как минимум 3 стратегии джойнов.
Вот ваш индекс V1_EMARCH_SEARCH.MESSAGE_ID неуникальный, поле SEARCH_CONTENT не содержит.
В вашем случае циклы с поисками оказались выгоднее. Но это не значит, что они будут выгодными всегда, при любом количестве записей.

ну так на то статистика и придумана чтобы определять что выгоднее
6 апр 12, 17:17    [12377717]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить