Имя: Пароль:
1C
1C 7.7
v7: 1SQLite. Временные таблицы.
0 Asakra
 
21.10.14
19:42
Кто знает как заставить SQLite использовать индекс временной таблицы?

Табличка используется в LEFT JOIN в табличном поле. Источник данных табличного поля Справочник.Номенклатура.

SELECT
ТМЦ.*,
ОстаткиПоСкладам.Склад1,
ОстаткиПоСкладам.Склад2
FROM
[Справочник.Номенклатура] AS ТМЦ
LEFT JOIN vt_ОстаткиПоСкладам AS ОстаткиПоСкладам
ON ТМЦ.ID = ОстаткиПоСкладам.ТМЦ

Табличку vt_ОстаткиПоСкладам индексирую так:
CREATE UNIQUE INDEX ТМЦ ON vt_ОстаткиПоСкладам(ТМЦ ASC)

Если выполняю этот запрос в консоли, то там видно, что основное время тратиться на скан vt_ОстаткиПоСкладам и индекс не используется.

Может я как-то не правильно индекс создаю? Подскажите как правильно?
1 orefkov
 
21.10.14
20:08
(0)
что explain query plan показывает?
Индекс до запроса создаешь?
Он точно на момент выполнения запроса существует?
2 Asakra
 
21.10.14
20:10
(1) да точно до запроса
временная табличка не меняется до закрытия формы
explain query plan щас гляну.
3 orefkov
 
21.10.14
20:12
Возможно имя индекса "Тмц" не уникально, и он не созается?
select * from sqlite_master where name = 'ТМЦ'
что выдает?
4 Asakra
 
21.10.14
20:15
(3)
order    from    detail                
0    0    SCAN TABLE sqlite_master (~100000 rows)                
                        
????????? ??????????                        
addr    opcode    p1    p2    p3    p4    p5
0    Trace    0    0    0         00
1    String8    0    1    0    ???    00
2    Goto    0    16    0         00
3    OpenRead    0    1    0    5    00
4    Rewind    0    14    0         00
5    Column    0    1    2         00
6    Ne    1    13    2    collseq(BINARY)    69
7    Column    0    0    4         00
8    Column    0    1    5         00
9    Column    0    2    6         00
10    Column    0    3    7         00
11    Column    0    4    8         00
12    ResultRow    4    5    0         00
13    Next    0    5    0         01
14    Close    0    0    0         00
15    Halt    0    0    0         00
16    Transaction    0    0    0         00
17    VerifyCookie    0    5    0         00
18    Goto    0    3    0         00
5 Asakra
 
21.10.14
20:18
(1)                         
order    from    detail                
0    0    SCAN TABLE Справочник.Номенклатуры AS sc156 VIRTUAL TABLE INDEX 2:PDESCR;    10 !$ 0p nHyd!   *4 (~0 rows)                
1    1    SCAN TABLE vt_ОстаткиПоСкладам AS ОстаткиПоСкладам (~100000 rows)
6 Asakra
 
21.10.14
20:20
(3) показывает index name ТМЦ
7 Asakra
 
21.10.14
20:22
(4) тут не было индекса, т.к. индекс был idx_ТМЦ. пробовал до этого иное имя задавать и забыл.
8 Asakra
 
21.10.14
21:51
ОПУПЕТЬ!
заметил, что если поставить условие
where
ОстаткиПоСкладам.ТМЦ > 0

то индекс включается.

перекинув в джойне сравнение
ON ОстаткиПоСкладам.ТМЦ = ТМЦ.ID

завел индекс!!!

пошел пересматривать все запросы с ВТ...
9 Ник второй
 
21.10.14
22:00
Я что то не понял, 1С работает на SQLite ?
10 Asakra
 
21.10.14
22:01
(9) угу
11 H A D G E H O G s
 
21.10.14
22:02
(8) Тип соединения какой?
hashjoin
mergejoin
nested loops

?

Индекс (полностью и православно) будет использован только в последнем случае.
12 Asakra
 
21.10.14
22:06
(11) я не знаю как это узнать...
13 Ник второй
 
21.10.14
22:18
(11) Это с чего это в нестед лупс будет использован индекс?

Как бы сравнивать землю и небо
14 Ник второй
 
21.10.14
22:20
(13) + Не влияет выбор плана поиска данных от способа соединения
15 H A D G E H O G s
 
21.10.14
22:28
(13) С фундаментальных принципов вселенной.
16 H A D G E H O G s
 
21.10.14
22:28
(14) Глупости какие.
17 orefkov
 
21.10.14
22:44
(11)
В sqlite вроде только nestedd loops, хотя я давно не отслеживал развитие, может, уже и другие типы есть.
(13)
Как раз и будет использован, для поиска во второй таблице.
18 Ник второй
 
22.10.14
06:45
(15) Читаем до просветления хотя бы вики:
https://ru.wikipedia.org/wiki/Алгоритм_соединения_вложенными_циклами
19 Ник второй
 
22.10.14
06:45
(16) Ваши доказательства
20 Ник второй
 
22.10.14
06:47
(17) Далеко не факт что будет использован. Факт использования или не использования зависит от наличия индексов, а не от выбора способа соединения. Или вы считаете, что если оптимизатор выбрал план запроса с нестед лупс, то на вторую таблицу создал необходимые индексы, мда....
21 orefkov
 
22.10.14
07:24
(20)
Я бы вам тоже посоветовал читать до просветления первоисточники:
https://www.sqlite.org/optoverview.html
https://www.sqlite.org/cvstrac/wiki?p=PerformanceTuning

Где вы кстати увидели, что оптимизатор должен сам создать индексы? Как-раз спрашивалось, почему он не использует существующий индекс.
Да и к тому же, современный sqlite - таки да, умеет и сам создавать временный индекс на время запроса, если посчитает это выгодным - https://www.sqlite.org/optoverview.html#autoindex
22 Ник второй
 
22.10.14
08:51
(21) Читай внимательно (11) с которого началась дискусия.

Получается если есть нестед лупс то всегда будет использоваться индекс из этого следует:
1. Если нет индексов, то оптимизатор ни когда не использует нестед лупс - что является ложным определением
2. Если есть индекс, то оптимизатор использует только нестед лупс, что тоже ложно.


Спасибо за наводку, что sqlite умеет сам в процессе создавать индекс.
23 Ник второй
 
22.10.14
08:59
(21) +

SQLite implements joins using nested loops with the outer loop formed by the first table in the join and the inner loop formed by the last table in the join. So for the example above you would have:

    For each row in a:
      For each row in b such that b.y=a.x:
        Return the row