Форум: "Базы";
Текущий архив: 2002.10.21;
Скачать: [xml.tar.bz2];
ВнизМастерам. Подскажите Найти похожие ветки
← →
Tornado (2002-09-27 09:25) [0]Есть БД Access, более 300 000 записей. Выполняю запрос с помощью компонента ADOQuery. Запрос следующего вида:
DM1.ADOQuery1.SQL.Add("SELECT * FROM PEOPLE WHERE
NAME LIKE " + name_s + "AND STREET LIKE" + street_q + "AND DOM LIKE" + house + "AND KV LIKE" + kv + "AND TEL LIKE" + q_phone + "ORDER BY NAME");
где: name_s, street_q, house, kv, q_phone - переменные, получающие значения из текстовых полей, заполняемых пользователем. Поля в таблице все индексированы, имеется ключевое автоинкременентное поле ID.
Но запрос выполняется очень долго, порядка 6-7 сек на машине CPU 1000, ОЗУ 256 и т.д., боюсь представить что будет на более слабых машинах...Может можно как-то оптимизировать запрос или есть какие-то другие способы увеличить быстродействие, подскажите пожалуйста. Спасибо.
← →
Johnmen (2002-09-27 09:45) [1]Не думаю, что всегда осуществляется поиск сразу по всем частично заданным значениям всех полей !
Посему : если не задано значение, так и не делай на соотв.поле LIKE ... в запросе.
← →
Anatoly Podgoretsky (2002-09-27 09:56) [2]При таком количестве данных и с таким диким запросом, будь благодарен, что вообще выполняется за такое малое время
← →
Tornado (2002-09-27 13:22) [3]ОК, согласен, запрос диковат, но тогда подскажите, уважаемые знатоки, как это сделать лучше? Примерчик если можно. Спасибо.
← →
Johnmen (2002-09-27 13:33) [4]>Tornado © (27.09.02 13:22)
>...подскажите, уважаемые знатоки, как это сделать лучше?
Что получше ? И в каком смысле "получше" ?
← →
ЮЮ (2002-09-27 13:37) [5]Посмотри, сколько выполняется запрос по самому существенному полю
SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s
Если существенно быстрее, то затем делать подзапросы, т.е. проверку уже значительно меньшего объема:
SELECT * FROM
(SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s) names
WHERE STREET LIKE" + street_q
← →
BlackTiger (2002-09-27 13:40) [6]Ну, во-первых, сколько бы ты не индексировал, LIKE не будет использовать твои индексы. Индексы работают при ПРЯМОМ задании значений или при BETWEEN. И не делай LIKE сразу по всем полям, будет выполняться n-кратный "full scan", где n - количество полей.
Да и вообще, 6-7 секунд для такого запроса (а Акксессе) ЭТО ОЧЕНЬ БЫСТРО!
Хочешь быстрее - меняй технологию фильтрации на значения без маски (BETWEEN [...] AND [...]).
← →
Tornado (2002-09-27 15:03) [7]> ЮЮ © (27.09.02 13:37)
Я зделал как Вы сказали, но запрос не работает. Что тут не так?
DM1.ADOQuery1.SQL.Add("SELECT * FROM");
DM1.ADOQuery1.SQL.Add("SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s)name_s;
DM1.ADOQuery1.SQL.Add("WHERE STREET LIKE " + street_q);
Ошибка в предложении FROM
← →
Johnmen (2002-09-27 15:21) [8]1. Проверь наличие скобочек в теле запроса
2. Такой синтаксис может не поддерживаться в Access
← →
roottim (2002-09-27 15:32) [9]дело в том, что индексы не работают, если присутствует оператор LIKE..
здесь необходимо разделить поиск на точный и "неочень" :-)
использовать =, тогда сработают индексы..
← →
Tornado (2002-09-27 16:08) [10]> roottim (27.09.02 15:32)
Вы не подскажите как это сделать? "=" я не могу использовать, т.к. пользователь как правило будет вводить только часть искомого слова.
> Johnmen © (27.09.02 15:21)
Да, видимо скобки нужны в подзапросе, только где их ставить?
Access поддерживает подобные запросы вроде, в хелпе написано.
В принципе понятно, только вот с кавычками да скобками гемморой...
DM1.ADOQuery1.SQL.Add("SELECT * FROM");
DM1.ADOQuery1.SQL.Add("SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s) names; {выделенное жирным - это что такое?}
DM1.ADOQuery1.SQL.Add("WHERE STREET LIKE " + street_q);
Помогите...
← →
Johnmen (2002-09-27 16:29) [11]1.
DM1.ADOQuery1.SQL.Add("SELECT * FROM");
DM1.ADOQuery1.SQL.Add("((SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s) names)"); {выделенное жирным - это что такое?}
DM1.ADOQuery1.SQL.Add("WHERE STREET LIKE " + street_q);
2. names - по-видимому, алиас для поля...
← →
Johnmen (2002-09-27 16:29) [12]1.
DM1.ADOQuery1.SQL.Add("SELECT * FROM");
DM1.ADOQuery1.SQL.Add("((SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s) names)"); {выделенное жирным - это что такое?}
DM1.ADOQuery1.SQL.Add("WHERE STREET LIKE " + street_q);
2. names - по-видимому, алиас для запроса...
← →
BlackTiger (2002-09-28 22:31) [13]Ну, во-первых, "кавычки, кавычки и еще раз ... скобки".
Например нужно отобрать все, что содержит текст "ABC". Синтаксис такой:
SELECT * FROM Table WHERE Field LIKE "*ABC*" ORDER BY Field2.
Точнее для дельфы:
SQL.Add("SELECT * FROM Table WHERE Field1 LIKE ""*" + Edit1.Text+"*"" ORDER BY Field 2");
Если не LIKE почему-то не сработает, то либо меняй одинарные кавычки на двойные, либо используй функцию InStr:
SQL.Add("SELECT * FROM Table WHERE (InStr(Field1,""" + Edit1.Text + """,0)>0) ORDER BY Field2");
А о производительности в этом случае лучше позабыть. Либо удобства, либо производительность :-(
← →
ЮЮ (2002-09-30 04:52) [14]SELECT * FROM
(SELECT * FROM PEOPLE WHERE NAME LIKE " + name_s) names
WHERE STREET LIKE" + street_q
names - это алиас для подзапроса. Синтаксис такой при использовании подзапросов. :-)
А по части использования BETWEEN или >= и <= для участия в подзапросе и того, что пользователь как правило будет вводить только часть искомого слова. Если ограничить пользователя тем, что он может искать только по началу поля, т.е. только по шаблону, например
STREET LIKE "Светлан%", то это равнозначно выражению
STREET BETWEEN "Светлан" AND "Светлан Я"
← →
Психиатр (2002-09-30 09:28) [15]>ЮЮ © (30.09.02 04:52)
>STREET LIKE "Светлан%", то это равнозначно выражению
>STREET BETWEEN "Светлан" AND "СветланЯ"
Разве ? А как же "Светлан Я Пупкина" ?
← →
Tornado (2002-09-30 10:54) [16]Я тут проверил, фильтр работает быстрее запроса...Может использовать фильтр? Что думают Мастера по этому поводу?
P.S. У меня есть программка, тел. справочник по Нижнему Новгороду, там очень итересно реализован запрос (или фильтр?), поиск занимает примерно 1, максимум 2 секунды, отображается прогресс баром и т.д. Прога написана толи на Дельфях, толи на C++ Builder. Првда имеет свой собственный формат БД с расширением *.phn. Записей тоже порядка 500 000, а размер всего лишь порядка 6 мег...Как это итнрнсно сднлано?
← →
Desdechado (2002-09-30 10:58) [17]фильтр отрабатывает на клиенте, а запрос - на сервере. И что будет быстрее, зависит от многих условий.
Расширение можно любое приписать.
← →
sniknik (2002-09-30 12:07) [18]лутшее решение уже прозвучало, использовать = вместо LIKE где возможно а где нет выбирать уже из подзапроса.
для интереса
запрос
SELECT * FROM 1saccsel
на таблице 418868 запись отрабатавает 18.32сек.
SELECT * FROM 1saccsel where Time = "BAOCGW"
на той же таблице возвращает 208зап за 1.94сек
с индексированным полем Time работает за 0.01сек !!!!!!
SELECT * FROM 1saccsel where Time LIKE "BAOCGW"
выполняется за 2.89сек
с индексированным полем Time ~ те же 2.75
выводы можно сделать. и фильтр не поможет т.к. выбрать все и отфильтровать нужное в моем случае горааааздо дольше. Использовал ADO,Jet база mdb ест-твенно локально.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.10.21;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.008 c