Использование индексов

asviridenkov
Дата: 16.07.2012 15:18:55
Столкнулся с занятной вещью в 2.5.2SC
Есть таблицы customers(region1 varchar) и regions(code varchar, name_ru varchar)

По name_ru есть индекс,
CREATE INDEX REGIONS_IDX1 ON REGIONS COMPUTED BY (upper(name_ru));


По region1 тоже
CREATE INDEX CUSTOMERS_R1 ON CUSTOMERS (REGION1);


Проверяем
select code from regions where upper(name_ru) like 'ИВАНОВО%'

PLAN (REGIONS INDEX (REGIONS_IDX1))

Так какого фига?
select * from customers c
where c.region1 in (select code from regions where upper(name_ru) like 'ИВАНОВО%')

PLAN (REGIONS INDEX (PK_REGIONS))
PLAN (C NATURAL)

Ни один ни другой индекс не задействованы
Гаджимурадов Рустам
Дата: 16.07.2012 15:21:46

А проверь всё то же самое, но без Upper.

Posted via ActualForum NNTP Server 1.5

asviridenkov
Дата: 16.07.2012 15:26:02
Гаджимурадов Рустам
А проверь всё то же самое, но без Upper.



То же самое
dimitr
Дата: 16.07.2012 15:39:56
индекс по CUSTOMERS никогда не использовался и не может (в таких ситуациях). А для коррелированного подзапроса выгоднее использовать только лишь PK, второй индекс быстрее выборку никак не сделает.
asviridenkov
Дата: 16.07.2012 15:46:08
dimitr
индекс по CUSTOMERS никогда не использовался и не может (в таких ситуациях).


В таких - это с подзапросом?
Почему тогда
select * from customers c where c.region1 in (1,2,3)

PLAN (C NATURAL)

dimitr
А для коррелированного подзапроса выгоднее использовать только лишь PK, второй индекс быстрее выборку никак не сделает.

А с какой радости подзапрос коррелированный? Что мешает его выполнить один раз?
Dimitry Sibiryakov
Дата: 16.07.2012 15:51:36

dimitr
индекс по CUSTOMERS никогда не использовался и не может (в таких ситуациях).

То, что он никогда не использовался это понятно, но ведь теоретически запрос можно
вывернуть наизнанку и таки его задействовать:
for select distinct code from regions
  where upper(name_ru) like 'ИВАНОВО%' into :code do
  begin
   select * from customers c where c.region1=:code
   ....
  end

Posted via ActualForum NNTP Server 1.5

dimitr
Дата: 16.07.2012 15:53:50
asviridenkov
В таких - это с подзапросом?

да, с IN

asviridenkov
Почему тогда
select * from customers c where c.region1 in (1,2,3)

PLAN (C NATURAL)

а нефиг сравнивать число с варчаром

asviridenkov
А с какой радости подзапрос коррелированный?

потому что его таким сервер делает самостоятельно, превращая IN в EXISTS. Иначе он будет выполняться ну очень медленно, ибо см. ниже.

asviridenkov
Что мешает его выполнить один раз?

отсутствие буферизации результатов подзапросов
kdv
Дата: 16.07.2012 15:56:44
asviridenkov
Почему тогда
select * from customers c where c.region1 in (1,2,3)
PLAN (C NATURAL)

ну, наверное индекса нет по region1. или у него селективность плохая.

select * from employee e where e.emp_no in (1, 2, 3)
PLAN (E INDEX (RDB$PRIMARY7, RDB$PRIMARY7, RDB$PRIMARY7))
dimitr
Дата: 16.07.2012 15:57:19
Dimitry Sibiryakov
теоретически запрос можно вывернуть наизнанку

код открытый - вперед. И не забудь подумать, не угробит ли сортировка из-за DISTINCT возможные плюсы такой "изнанки"
asviridenkov
Дата: 16.07.2012 16:07:11
dimitr
а нефиг сравнивать число с варчаром


Да, при замене на строки взял индекс
"Это нельзя понять, это можно только запомнить"(с)

dimitr
отсутствие буферизации результатов подзапросов

Жаль, жаль