Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
8-68878
Друмлин
2002-05-21 12:32
2002.10.21
проблемы с AVI


1-68802
NaM
2002-10-09 18:59
2002.10.21
---|Ветка была без названия|---


14-68920
vopros
2002-10-01 10:57
2002.10.21
Что делать? Как жить?


1-68780
123000
2002-10-11 19:23
2002.10.21
Опять Richedit


8-68881
Rocky Jr.
2002-06-22 06:22
2002.10.21
Real Player и Guitar Pro





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский