Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Очень медленно выполняется запрос. [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 раз?


Наверх

Титульная страница Поиск, карта сайта Написать письмо