|
|
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
Есть таблица Goods(id int, name varchar(255)). По полю ID построен индекс. А также процедура: create procedure __temp(_id int) define _a int; let _a = 1; insert into zTable(id, name) select id, name from Goods where id = _id or _a = 0; insert into zTable(id, name) select id, name from Goods where id = _id or 1 = 0; end procedure; Индекс используется только во втором селекте в процедуре. Получается во первом случае он последовательно идет по строкам и только после получения строки проверяет удовлетворяют ли ее данные условию фильтра, в отличие от второго случая, когда он сразу же отбрасывает лишний кусок фильтра. Что можно сделать? (в смысле как заставить использовать индекс). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 11:55 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
Valentyn PidburtnyiЕсть таблица Goods(id int, name varchar(255)). По полю ID построен индекс. А также процедура: create procedure __temp(_id int) define _a int; let _a = 1; insert into zTable(id, name) select id, name from Goods where id = _id or _a = 0; insert into zTable(id, name) select id, name from Goods where id = _id or 1 = 0; end procedure; Индекс используется только во втором селекте в процедуре. Получается во первом случае он последовательно идет по строкам и только после получения строки проверяет удовлетворяют ли ее данные условию фильтра, в отличие от второго случая, когда он сразу же отбрасывает лишний кусок фильтра. Что можно сделать? (в смысле как заставить использовать индекс). При выроботке плана выполниния запроса оценивается результат условия 'or' и если есть предположение, что если хоть один из операндов принимает значение ложь то использование индекса смысла не имеет. В вашем сучае _a = 0; всегда ложно. Ситуацию можно сравнить с ситуацией когда в таблице существует поле _a и оно не входит ни в один из индексов. Тогда ситуация сразу станет прозрачной, а поведение оптимизатора соответствующим логике. Резюме: Я подозреваю, что оптимизатор не видит разницы между полем и переменной. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 12:24 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
onstat- Я подозреваю, что оптимизатор не видит разницы между полем и переменной. Да, все указывает на это:( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 12:42 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
Кстати, таково поведение практически всех оптимизаторов СУБД. По этому, в критичных запросах в процедурах я предпочитаю использовать временную табличку из одной строки, в которую занести значения всех необходимых переменных. После этого, оптимизатор ведет себя более умно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 13:07 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
DaugavaКстати, таково поведение практически всех оптимизаторов СУБД. По этому, в критичных запросах в процедурах я предпочитаю использовать временную табличку из одной строки, в которую занести значения всех необходимых переменных. Можно пример запроса? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 16:15 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
[quot onstat При выроботке плана выполниния запроса оценивается результат условия 'or' и если есть предположение, что если хоть один из операндов принимает значение ложь то использование индекса смысла не имеет. В вашем сучае _a = 0; всегда ложно. [/quot] Я что то не понял твоей логики... Если "_a = 0; всегда ложно", то что тогда можно сказать о 1=0 ? Вроде, как все наоборот, по выражению _a = 0 оптимизатор еще ничего не знает (обрабатывается как константа = переменная), так как подстановка конкретного значения произойдет уже на этапе выполнения, после построения плана запроса. А вот во втором случае 1=0 всегда ложно и остается только один фильтр, для которого индекс используется почти всегда (за редким исключением). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 22:29 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
[quot onstatЯ подозреваю, что оптимизатор не видит разницы между полем и переменной.[/quot] Подозреваю, что видит :) При анализе "поле_таблицы" > 5 оптимизатор уже имеет статистику(если она собиралась), по которой он может определить избирательность данного фильтра и предположить примерное кол-во строк в выборке, заодно и оценив применимость индекса, (если он есть). При анализе же "поле_таблицы" > "переменная" оптимизатор не может знать заранее все значения переменной, соответственно и построение плана может быть совершенно другим.Тут , кстати, оптимизатор может построить план, удовлетворяющий первому значению переменной, что потом может вылезти боком на других значениях... При анализе условия "переменная" > 5 оптимизатор тоже ничего не может сказать заранее, какой (ложь или истина) будет результат, соответственно и проверять надо будет все строки таблицы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2005, 22:47 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
vasilis Я что то не понял твоей логики... Если "_a = 0; всегда ложно", то что тогда можно сказать о 1=0 ? Вроде, как все наоборот, по выражению _a = 0 оптимизатор еще ничего не знает (обрабатывается как константа = переменная), так как подстановка конкретного значения произойдет уже на этапе выполнения, после построения плана запроса. А вот во втором случае 1=0 всегда ложно и остается только один фильтр, для которого индекс используется почти всегда (за редким исключением). Да действительно, что то я сам запутался :(. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2005, 10:08 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
Получается, что план будет нормальным, если Информикс перекомпилирует процедуру, зная значение параметра. И насколько я понял такого сделать невозможно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2005, 10:31 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
Поддерживаю vasilis :-). Обещанный пример. В запросе участвует десяток таблиц, связанных между собой констрейнтами. Среди них одна из небольших (40к записей). Если по индексированому полю этой таблицы делать запрос с указанием переменной, то оптимизатор предпочтет этот индекс не использовать. Если, же вместо переменной указать константу, или как уже описывалось выше, временную табличку, все получается Ок. Нарывался на подобное в 7.x,9x и в M$SQL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2005, 10:31 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
vasilis[quot onstatЯ подозреваю, что оптимизатор не видит разницы между полем и переменной. Подозреваю, что видит :) При анализе "поле_таблицы" > 5 оптимизатор уже имеет статистику(если она собиралась), по которой он может определить избирательность данного фильтра и предположить примерное кол-во строк в выборке, заодно и оценив применимость индекса, (если он есть). При анализе же "поле_таблицы" > "переменная" оптимизатор не может знать заранее все значения переменной, соответственно и построение плана может быть совершенно другим.Тут , кстати, оптимизатор может построить план, удовлетворяющий первому значению переменной, что потом может вылезти боком на других значениях... При анализе условия "переменная" > 5 оптимизатор тоже ничего не может сказать заранее, какой (ложь или истина) будет результат, соответственно и проверять надо будет все строки таблицы[/quot] Здесь имелось ввиду, что если есть условие 'or' с участием двух полей, и только одно из них индексировано. Множество всех значений удовлетворяющих условию where будет зависеть от обоих полей. То есть, по не индксированному полю всеравно нужно будет искать перебором всех значений таблицы. В случае же с константами в условии where, константное выражение, может быть вычислено до начала работы оптимизатора. Все это только предположение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2005, 10:32 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
DaugavaПоддерживаю vasilis :-). Обещанный пример. В запросе участвует десяток таблиц, связанных между собой констрейнтами. Среди них одна из небольших (40к записей). Если по индексированому полю этой таблицы делать запрос с указанием переменной, то оптимизатор предпочтет этот индекс не использовать. Если, же вместо переменной указать константу, или как уже описывалось выше, временную табличку, все получается Ок. Я так понимаю не важно в данном случае большая таблица или нет(на небольших как раз неиспользование индекса не говорит ни о чем: часто оптимизатору физически быстрее сделать скан). Главное: ты добился того, что информикс индекс все-же использовал. Но как?? Я не могу понять каким боком прилепить врем таблицу.:(( insert into zTable(id, name) select g.id, g.name from Goods g join zTempTable z on z.id = g.id or z.a = 0; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2005, 18:21 |
|
||
|
Оптимизатор игнорирует индекс
|
|||
|---|---|---|---|
|
#18+
vasilis При анализе же "поле_таблицы" > "переменная" оптимизатор не может знать заранее все значения переменной, соответственно и построение плана может быть совершенно другим. Тут, кстати, оптимизатор может построить план, удовлетворяющий первому значению переменной, что потом может вылезти боком на других значениях... В каких случаях он строит такой план?? Судя по моим экспериментам, в данном случае он такого плана не строит (т.е. плана, удовлетворяющего значениям параметров процедуры при ее первом запуске). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2005, 19:09 |
|
||
|
|

start [/forum/topic.php?fid=44&tid=1609023]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
65ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
32ms |
get tp. blocked users: |
1ms |
| others: | 238ms |
| total: | 382ms |

| 0 / 0 |
