![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Очень медленно выполняется запрос. [D7]
3APA3A © (2004-09-11 12:35:00)Есть две таблицы
CREATE TABLE T1(NAME VARCHAR(64), SURNAME VARCHAR(64), ID INT);
CREATE TABLE T2(INFO VARCHAR(64), T1_ID INT);
То есть - в первой таблице хранятся сущности, а во второй - дополнительная информация к ним...
Делаю поиск
SELECT * FROM T1 WHERE UPPER(NAME) like UPPER('%lalala%') OR UPPER(SURNAME) like UPPER('%lalala%') OR ID IN (SELECT T1_ID FROM T2 WHERE UPPER(INFO) like UPPER('%lalala%'));
В таблице T1 ~ 3500 записей
В таблице T2 ~ 6500 записей.
Под FB 1.5.1 CS этот запрос выполняется от 1 минуты до 2-х.
Абсолютно аналогичные таблицы создаю для Paradox - запрос длится доли секунды.
Индексов нигде нет.
Почему такая разница во времени выполнения?
3APA3A (2004-09-12 22:52:00) [1]Да нет, это "lalala" на самом деле вовсе не "lalala", оно из приложения передается => надо UPPER()
Видимо, из-за отсутствия "%" в начале строки.
Тогда такой вопрос
UPPER(T1.NAME) LIKE 'LALALA%' - использует индексы?
Мне кажется - нет...
Да и вообще - где про это почитать можно (конкретно, про то, где и когда IB/FB/Yaffil использует индексы, желательно с тонкостями для каждой СУБД), а то собирать информацию такими кусочками даже не интересно...
sniknik (2004-09-12 20:45:00) [2]> Может Вы еще что полезное посоветуете?
много их не делай если скорость записи в таблицу критична.
потом по твоему запросу
вот это
UPPER(T1.NAME) LIKE UPPER('%lalala%')
индексов не использует (т.что бессмысленно делать), да и UPPER для константной строки лишний (это вообше а не по индексам, трудно разве написать '%LALALA%'?), это не дельфи который все приведет к нужному виду.
только 2 индекса будут актуальны по T1.ID и T2.T1_ID
кстати а вот такое условие индекс использует (догадайся почему? ;о))
T1.NAME LIKE 'LALALA%'
3APA3A (2004-09-12 20:32:00) [3]to sniknik
Да. Спасибо. Разобрался. Еще мануальчики кое-какие почитал...
to All
По поводу индексов. Сидел сейчас, ждал свою ХП 13 минут. Сделал индекс по 1 полю - 18 секунд. Результат, конечно, впечатляет, но хотелось бы узнать к каким полям надо создавать индексы. Я пока руководствуюсь следующим - есть поле в условии после WHERE ... - создаю по нему индекс. Может Вы еще что полезное посоветуете?
sniknik (2004-09-11 23:54:00) [4]связь таблиц по условию, условие T1.ID = T2.T1_ID, запись из второй таблицы с поля T1_ID ставится в соответствие с записью из первой по полю ID.
неявно для построения такой связи строится временный индекс если его нет. (поэтому желательно чтобы он был ;) если собираешся это использовать)
а вообще выполни запрос только со связью без остального условия все ясно и станет.
вот так
SELECT * FROM T1 INNER JOIN T2 ON (T1.ID = T2.T1_ID)
и смотри в гриде результат. как из какой таблици поля расположились.
3APA3A (2004-09-11 23:26:00) [5]Да, такой вопрос - можно мне "на пальцах" объяснить, что делает JOIN.
3APA3A (2004-09-11 14:40:00) [6]Да индексы-то я создам конечно, просто их не было в процессе тестирования...
Спасибо. Запрос работает моментально, ищет то что надо, только некоторые записи дублирует. Но с этим я уже сам разберусь...
tnx...
-SeM- (2004-09-11 13:32:00) [7]А еще добавь в конец ORDER BY T2.T1_ID, чтобы задействовать индекс T2
-SeM- (2004-09-11 13:16:00) [8]
> Индексов нигде нет.
Как вообще? Срочно создай primary key на поле ID таблицы T1 и foreign key на поле T1_ID для таблицы Т2.
А запрос таков:
SELECT T1.* FROM T1
INNER JOIN T2 ON (T1.ID = T2.T1_ID)
WHERE (((UPPER(T1.NAME) LIKE UPPER('%lalala%')) or (UPPER(T1.SURNAME) LIKE UPPER('%lalala%')) or (UPPER(T2.INFO) LIKE UPPER('%lalala%'))))
3APA3A (2004-09-11 12:43:00) [9]Такое чувство, что подзапрос "(SELECT T1_ID FROM T2 WHERE UPPER(INFO) like UPPER('%lalala%'))" выполняется для каждой итерации внешнего запроса. А по сути задачи - этого не надо делать. Может как-то можно "развернуть" этот запрос, что-бы подзапрос выполнялся 1 раз?