Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];

Вниз

Оптимизация запроса   Найти похожие ветки 

 
Andrey   (2004-05-31 10:13) [0]

Проблема в следующем: при попытке выполнить запрос к таблице, состоящей из 6,000,000 записей, комп выполняет его где-то секунд 30. Открытие той же таблицы через TTable (с установленным индексом) происходит почти сразу (через пару секунд). Отсюда и вопрос, что делать? (без запроса не обойтись)


 
mutabor   (2004-05-31 10:15) [1]

база какая?


 
Vlad ©   (2004-05-31 10:16) [2]


> Andrey   (31.05.04 10:13)  

Приведи запрос


 
Andrey   (2004-05-31 10:17) [3]

Написано же в заголовке: D6, MySQL. Версию MySQL не знаю, но одна из последних


 
Andrey   (2004-05-31 10:17) [4]

select * from contract,client,fund
where contract.fundid=fund.fundid and contract.clt_auto=client.clt_auto
and (contract.ctp_auto=6478102 or contract.ctp_auto=684954 or contract.ctp_auto=409368)


 
Полный дурак   (2004-05-31 10:17) [5]


> Написано же в заголовке: D6, MySQL. Версию MySQL не знаю,
> но одна из последних


Это что, - запрос что-ли?


 
Andrey   (2004-05-31 10:21) [6]

Ну так что, есть какие-то варианты?


 
Vlad ©   (2004-05-31 10:23) [7]


> Andrey   (31.05.04 10:17) [4]

Индексы по всем полям cвязки есть ?
и еще, возможно or тормозит запрос, попробуй оставить только contract.ctp_auto=6478102, остальное убрать (ради эксперимента)


 
Sergey13 ©   (2004-05-31 10:25) [8]

2Andrey   (31.05.04 10:17) [4]
Индексы есть?


 
DenK_vrtz ©   (2004-05-31 10:27) [9]

при выборе поля всех трех таблиц нужны (SELECT * ...)?


 
Andrey   (2004-05-31 10:29) [10]

Индексы есть по всем полям.

Запрос модифицировал:

select * from contract,client,fund
where contract.fundid=fund.fundid and contract.clt_auto=client.clt_auto
and (contract.ctp_auto IN (6478102,684954,409368));

Тормозит все равно.

А когда в Table ставлю Filter=ctp_auto=6478102 or и т.д. , нормально работает!


 
Vlad ©   (2004-05-31 10:32) [11]


> Andrey   (31.05.04 10:29) [10]

Я же сказал, попробуй оставить только одно значение contract.ctp_auto = 6478102 без всяких OR или IN (что одно и тоже)


 
DenK_vrtz ©   (2004-05-31 10:32) [12]

СТОП.
Так результирующий курсор будет иметь ограничения по 3-м условиям?
исходя из - (contract.ctp_auto=6478102 or contract.ctp_auto=684954 or contract.ctp_auto=409368)

Если так, то сначала ограничь набор contract, а потом сделай объединение с client,fund.


 
Andrey   (2004-05-31 10:32) [13]

Еще особенность: в таблице contract примерно 15 полей, в таблице client около 30. Нужны в запросе почти все


 
sniknik ©   (2004-05-31 10:34) [14]

не надо вводить в заблуждение (это мягко говоря)
вот это
select * from contract,client,fund
....
TTable не откроет ни через пару секунд ни вообще, запрос с обьеденением трех таблиц всегда медленнее чем выборка из одной (случай с TTable), поборотся за скорость конечно можно но это другая песня.
к примеру я бы (хотя я не работаю с MySQL) поставил бы условия с явным сравнением на первое место, на случай если MySQL выполняет условия поочередно, а обьеденение потом.


 
Andrey   (2004-05-31 10:34) [15]

"СТОП.
Так результирующий курсор будет иметь ограничения по 3-м условиям?
исходя из - (contract.ctp_auto=6478102 or contract.ctp_auto=684954 or contract.ctp_auto=409368)

Если так, то сначала ограничь набор contract, а потом сделай объединение с client,fund."

А ты примерчик не мог бы привести?


 
Andrey   (2004-05-31 10:38) [16]


> не надо вводить в заблуждение (это мягко говоря)
> вот это
> select * from contract,client,fund
> ....
> TTable не откроет ни через пару секунд ни вообще, запрос
> с обьеденением трех таблиц всегда медленнее чем выборка
> из одной (случай с TTable), поборотся за скорость конечно
> можно но это другая песня.

Ну это понятно. Без запроса не обойтись. В TTable я делал lookup-поля, но все равно потом нужен будет другой запрос (во время выполнения исходный запрос изменяется)


 
DenK_vrtz ©   (2004-05-31 10:39) [17]

если нигде не наврал, то так :)

SELECT * FROM
(SELECT * FROM contract WHERE ctp_auto IN (6478102,684954,409368)) contract, client, fund
WHERE contract.fundid=fund.fundid
AND   contract.clt_auto=client.clt_auto


 
Vlad ©   (2004-05-31 10:41) [18]

sniknik ©   (31.05.04 10:34) [14]


> запрос с обьеденением трех таблиц всегда медленнее чем выборка
> из одной (случай с TTable), поборотся за скорость конечно
> можно но это другая песня.

Как показали тесты на IB, при ~6 млн записях практически не заметно, три таблицы там объединяются или одна. Если есть необходимые индексы, то запрос срабатывает пулей.
Но как только в запрос добавляешь OR или IN, это серьезно сказывается на быстродействии.


 
Andrey   (2004-05-31 10:42) [19]


> если нигде не наврал, то так :)
>
> SELECT * FROM
> (SELECT * FROM contract WHERE ctp_auto IN (6478102,684954,409368))
> contract, client, fund
> WHERE contract.fundid=fund.fundid
> AND   contract.clt_auto=client.clt_auto

Блин. По-моему, select из select-a не работает. Но сейчас еще раз проверю


 
Andrey   (2004-05-31 10:46) [20]

Ага. По ctp_auto нету индекса, видимо в этом проблема?


 
Vlad ©   (2004-05-31 10:47) [21]


> Andrey   (31.05.04 10:46) [20]
> Ага. По ctp_auto нету индекса, видимо в этом проблема?

Естественно, индексы д.б. по всем полям, по к-рым происходит отбор.


 
DenK_vrtz ©   (2004-05-31 10:48) [22]

Andrey   (31.05.04 10:46) [20]

Так тебя ж сразу спросили про индексы!!!


 
Sandman25+1   (2004-05-31 10:49) [23]

Индексы по fund.fundid и client.clt_auto есть?


 
sniknik ©   (2004-05-31 10:50) [24]

Vlad ©   (31.05.04 10:41) [18]
т.е. хочеш сказать что декартово обьеденение трех таблиц по 6млн. записей такойже по скорости как открытие одной без обьеденений (как делает табле)?
позволь не поверить
а вот если есть ограничивающеее условие в силу которого вибирается малая часть то тут будет зависеть от того что было вначале обьеденение всего или выборка и последующее обьеденение малой части.
как сработает конкретный движок, вопрос, если есть анализатор запроса пофигу что где ставить. но на всякий случай... и вообще начал бы с тестов и доков что и как в конкретном движке работает (имхо).


 
Andrey   (2004-05-31 10:51) [25]


> Так тебя ж сразу спросили про индексы!!!

Ну, не заметил. Зато поговорили.
Кстати, селект из селекта все-таки не работает. Можно продолжить тему об этом.


 
Andrey   (2004-05-31 10:54) [26]


> Индексы по fund.fundid и client.clt_auto есть?

По ним есть - это первичные ключи


 
DenK_vrtz ©   (2004-05-31 10:57) [27]

Если не работает select из select"a, то SELECT * FROM contract WHERE ctp_auto IN (6478102,684954,409368) можно загнать во view

:) "но это уже совсем другая история"


 
Vlad ©   (2004-05-31 11:01) [28]


> sniknik ©   (31.05.04 10:50) [24]


> т.е. хочеш сказать что декартово обьеденение трех таблиц
> по 6млн. записей такойже по скорости как открытие одной
> без обьеденений (как делает табле)?

Есть основная таблица (6 млн записей) и есть 2 справочника, получаем декартово произведение трех таблиц, затем естественно связываем таблицы по ключевым полям и ограничиваем выборку по нек-му критерию (индексированному полю). Так вот - на глаз никакой разницы нет, что мы выбираем из одной, что из трех таблиц. Результат не заставляет ждать и секунды (Так на IB во всяком случае)


 
Andrey   (2004-05-31 11:04) [29]


> Индексы по fund.fundid и client.clt_auto есть?


Нет индексов по contract.fundid и contract.clt_auto. Может, из-за этого он вешается?


 
Nikolay M. ©   (2004-05-31 11:06) [30]


> Есть основная таблица (6 млн записей) и есть 2 справочника,
> получаем декартово произведение трех таблиц, затем естественно
> связываем таблицы по ключевым полям и ограничиваем выборку
> по нек-му критерию (индексированному полю). Так вот - на
> глаз никакой разницы нет, что мы выбираем из одной, что
> из трех таблиц. Результат не заставляет ждать и секунды
> (Так на IB во всяком случае)

А что, в IB нет оптимизатора запросов, который сам оптимальным образом расставляет порядок условий в WHERE? Даже в мускуле оптимизатор есть.


 
DenK_vrtz ©   (2004-05-31 11:06) [31]

Andrey   (31.05.04 11:04) [29]

в ромашку играем? Пробуй!


 
Andrey   (2004-05-31 11:07) [32]


> Есть основная таблица (6 млн записей) и есть 2 справочника,
> получаем декартово произведение трех таблиц, затем естественно
> связываем таблицы по ключевым полям и ограничиваем выборку
> по нек-му критерию (индексированному полю). Так вот - на
> глаз никакой разницы нет, что мы выбираем из одной, что
> из трех таблиц. Результат не заставляет ждать и секунды
> (Так на IB во всяком случае)

Хе. Не совсем. Я сейчас убрал условие по ctp_auto и он один хрен тормозит.


 
Vlad ©   (2004-05-31 11:12) [33]


> Andrey   (31.05.04 11:07) [32]


> Я сейчас убрал условие по ctp_auto

Да не надо совсем его убирать. Естественно будет тормозить, ты же выбираешь теперь произведение всех записей !
Говорю, сделай индекс по этому полю, и ограничивай без всяких OR или IN то есть просто ctp_auto = XXX


 
sniknik ©   (2004-05-31 11:13) [34]

Vlad ©   (31.05.04 11:01) [28]
вот!
> и ограничиваем выборку по нек-му критерию (индексированному полю).
это на твой взгляд делается после, на самом деле движок обычно сначала ограничивает, а обьеденение уже по 100записям к примеру (что в выборку вошло) делает, это большого времени не составляет,
убери условие ограничения (чтобы получить полное декартово произведение таблиц) и посмотри сколько времени займет.

> Нет индексов по contract.fundid и contract.clt_auto. Может, из-за этого он вешается?
одна из причин. для присоеденения по неиндексированному полу обычно строится временный индекс.


 
sniknik ©   (2004-05-31 11:16) [35]

полу = полю
;)
впрочем к какому нибудь неиндексированному(и противоположному) полу я бы тоже присоеденился... ;о))


 
Vlad ©   (2004-05-31 11:20) [36]


> sniknik ©   (31.05.04 11:13) [34]

а я разве с этим спорю, это делает оптимизатор практически во всех СУБД.
Речь о том, что если в ограничивающее условие впихнуть OR то будут заметные тормоза.


 
Andrey   (2004-05-31 11:26) [37]

Ну а как без OR обойтись?

Надо ограничивать по всем трем значениям!


 
Vlad ©   (2004-05-31 11:28) [38]


> Andrey   (31.05.04 11:26) [37]

Ты попробуй сначала, просто ради эксперимента. Может не в этом дело, тогда дальше думать будем. Нужно же локализовать проблему


 
sniknik ©   (2004-05-31 11:31) [39]

может оптимизатор с OR не справляется? на access/MSSQL такого не замечал.


 
Andrey   (2004-05-31 11:32) [40]

Да я попробовал - один хер не пашет.

Может, MySQL плохо делает декартово произведение или вообще тупит при работе с большими таблицами?



Страницы: 1 2 вся ветка

Форум: "Базы";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.031 c
1-1086886557
Ivolg
2004-06-10 20:55
2004.06.27
Копирование


14-1086697773
Обучающийся
2004-06-08 16:29
2004.06.27
Утилиты для измерения температуры CPU, материнской платы и др.


1-1087138341
Agent[007]
2004-06-13 18:52
2004.06.27
EAccessVolation


14-1086888391
Ilya_
2004-06-10 21:26
2004.06.27
Помогите пожалуйста с созданием Screen Saver.


11-1075885983
andrey1
2004-02-04 12:13
2004.06.27
компактный аналог TStringList





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский