Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация MySQL запроса 
:(
    Опции темы
Rigel
Дата 18.8.2008, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 24.7.2007
Где: Москва

Репутация: нет
Всего: нет



MySQL запрос такой (он работает, но даже при сорока тысячах книг, запрос из трех слов отрабатывается дольше таймаута вебсервера):
Код

SELECT DISTINCT IF(COUNT(DISTINCT word,sec)=$ArgCounter,art,0) AS qw 
FROM `dict2` 
WHERE $CyrString AND sec > 0 
GROUP BY art 
having qw

Дело в том, что он работает с очень большой таблицей, структура такая: поле art - это ID книги, поле word это ID слова, поле sec это ID секции в книге и поле cnt это сколько раз слово с этим ID встречается в секции. Нужно выбоать все книги, у которых в одной секции замечены все запрошенные слова. $ArgCounter - это количество поисковых слов (в текущей версии не используется), $CyrString - это условие, где ID слов перечисляются через OR. Таким образом, запрос примет, допустим, такой вид:
Код

SELECT DISTINCT IF(COUNT(DISTINCT word,sec)=3,art,0) AS qw 
FROM `dict2` 
WHERE (word='114' OR word='95' OR word='217') AND sec > 0 
GROUP BY art 
having qw

Проиндексированно только поле word, потому что размер только этого индекса почти пять гигабайт.


Это сообщение отредактировал(а) skyboy - 18.8.2008, 14:06
--------------------
С уважением. Rigel. http://www.smoliy.ru
PM MAIL WWW ICQ   Вверх
Akina
Дата 18.8.2008, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454



Навскидку получается нечто вроде
Код

Select `art`
From `dict2`
WHERE (word='114' OR word='95' OR word='217')
Group By `art`,`sec`
Having Count(`sec`)=3

Однако у меня есть огроменные подозрения, что не все ладно в королевстве Датском... 
Что означает AND sec > 0???


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Rigel
Дата 18.8.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 24.7.2007
Где: Москва

Репутация: нет
Всего: нет



Что-то я не заметил увеличения быстродействия (минут пять уже жду).
AND sec > 0 Означает, что наличие поисковых слов в заголовке (то есть до начала первой секции) не интересно. Это не принципиально, можно убрать из запроса.
--------------------
С уважением. Rigel. http://www.smoliy.ru
PM MAIL WWW ICQ   Вверх
Akina
Дата 18.8.2008, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454



Цитата(Rigel @  18.8.2008,  14:38 Найти цитируемый пост)
Что-то я не заметил увеличения быстродействия (минут пять уже жду).

Планы запрсов смотри... хотя если нет индексов, по-любому filesearch. А если индекс на 5 гиг - какое уж тут быстродействие...


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
solenko
Дата 18.8.2008, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



Цитата(Rigel @  18.8.2008,  11:35 Найти цитируемый пост)
Проиндексированно только поле word, потому что размер только этого индекса почти пять гигабайт.

Праздный интерес... Как на int поле получился индекс в 5 гиг? Сколько записей? 



--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Rigel
Дата 18.8.2008, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 24.7.2007
Где: Москва

Репутация: нет
Всего: нет



Четыреста пятьдесят два миллиона записей.
--------------------
С уважением. Rigel. http://www.smoliy.ru
PM MAIL WWW ICQ   Вверх
solenko
Дата 18.8.2008, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



Rigel, подумал, поискал, еще раз подумал и ничего. Скажите, у вас ведь запрос 
SELECT count(1)
FROM `dict2` 
WHERE (word='114' OR word='95' OR word='217')
выполняется так же долго?
Сколько записей он возвращает?

//как-то даже неудобно вам вопросы задавать, т.к., скорее всего помочь не смогу


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
solenko
Дата 18.8.2008, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



Кстати, вот тут прочитал инетрестную вещь... Индексы на больших таблицах могут только замедлять выборку. Насколько я понял, это связано с тем, что сервер не может загрузить индекс в память и потому значительно увеличивается кол-во операция чтения с диска.

Также, большой разброс данных по диску замедляет. Можно попробовать выполнить:
Цитата

myisamchk --sort-index --sort-records=1

*сколько это будет работать на вашей базе сложно представить



--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Akina
Дата 19.8.2008, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454



Не, подумал - ничего тебе не поможет походу... 
Например, для того чтобы попытаться ускорить написанный мной запрос, потребуется индекс по (`art`,`sec`) - а это почти 8 гигов, сервер столько при всем желании не закэширует.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Rigel
Дата 19.8.2008, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 24.7.2007
Где: Москва

Репутация: нет
Всего: нет



Цитата(solenko @ 18.8.2008,  22:03)
Rigel, подумал, поискал, еще раз подумал и ничего. Скажите, у вас ведь запрос 
SELECT count(1)
FROM `dict2` 
WHERE (word='114' OR word='95' OR word='217')
выполняется так же долго?
Сколько записей он возвращает?

//как-то даже неудобно вам вопросы задавать, т.к., скорее всего помочь не смогу

Те коды я написал "на глаз", сейчас проверил запрос:
SELECT count(1) FROM `dict2`  WHERE (word = '333'  OR  word = '3779'  OR  word = '480')
число 1368290 появилось секунды за две.

Добавлено через 7 минут и 12 секунд
Цитата(Akina @ 19.8.2008,  08:21)
Не, подумал - ничего тебе не поможет походу... 
Например, для того чтобы попытаться ускорить написанный мной запрос, потребуется индекс по (`art`,`sec`) - а это почти 8 гигов, сервер столько при всем желании не закэширует.

Так не бывает, чтобы нельзя было что-то сделать. Хотя бы от счетчика избавиться.
--------------------
С уважением. Rigel. http://www.smoliy.ru
PM MAIL WWW ICQ   Вверх
Akina
Дата 19.8.2008, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454



Цитата(Rigel @  19.8.2008,  10:52 Найти цитируемый пост)
появилось секунды за две

Вот собсно время обработки таблицы по твоему 5-гектарному индексу.
Но как только встречается нечто, не связанное с индексированным полем, начинает лопатиться вся база. Отсюда и время. Может, все-таки попробовать добавить необходимые запросу индексы? 

PS. Надеюсь, это не боевая БД, а модельная копия?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Rigel
Дата 19.8.2008, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 24.7.2007
Где: Москва

Репутация: нет
Всего: нет



Цитата(Akina @ 19.8.2008,  10:00)
Цитата(Rigel @  19.8.2008,  10:52 Найти цитируемый пост)
появилось секунды за две

Вот собсно время обработки таблицы по твоему 5-гектарному индексу.
Но как только встречается нечто, не связанное с индексированным полем, начинает лопатиться вся база. Отсюда и время. Может, все-таки попробовать добавить необходимые запросу индексы? 

PS. Надеюсь, это не боевая БД, а модельная копия?

Да, это копия на локальной машине. Настоящая база будет в несколько раз больше.
Я и надеюсь, что удасться избавиться, прежде всего, от счетчика... но пока что-то ничего в голову не лезет, вот я и написал сюда.  smile 
Что до дополнительных индексов - на моей машине с четырьмя гигами их наличие только замедляет работу. 
--------------------
С уважением. Rigel. http://www.smoliy.ru
PM MAIL WWW ICQ   Вверх
Magnifico
Дата 19.8.2008, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 23.1.2008
Где: Московская област ь

Репутация: 4
Всего: 17



исходя из струтуры таблицы заметил что ни одно поле не является уникальным идентификаторм строки
(многие субд этого не любят)
грубо говоря  в каждой книге много секций и еще больше слов
Цитата

art sec word cnt
1   1      1     1
1    1     2     3
1    2     3     5
1    2    4     10
2    1    1      7
2    1    1      5
2    2     1     4


Цитата

SELECT count(1) FROM `dict2`  WHERE (word = '333'  OR  word = '3779'  OR  word = '480')
число 1368290 появилось секунды за две

он активно использует индекс по word

может поделить большую таблицу на несколько  по смысловым группам.



--------------------
Всё  в  порядке   -   спасибо  зарядке  !
PM MAIL   Вверх
Magnifico
Дата 19.8.2008, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 23.1.2008
Где: Московская област ь

Репутация: 4
Всего: 17



Код

WHERE (word='114' OR word='95' OR word='217')

типы данных для word наверно varchar? , а для art  и  sec тоже varchar?
почему бы не использовать int или еще лучше (smallint, tinyint  ну или что там есть для мускула ... чтобы уписываться в диапазон )
в вашем уникальном случае все это скажется на производительности.

 


--------------------
Всё  в  порядке   -   спасибо  зарядке  !
PM MAIL   Вверх
solenko
Дата 19.8.2008, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 4
Всего: 67



Magnifico, да проблемма не в выборке а в постобработке результат. 
Цитата(Rigel @  19.8.2008,  08:52 Найти цитируемый пост)
SELECT count(1) FROM `dict2`  WHERE (word = '333'  OR  word = '3779'  OR  word = '480')число 1368290 появилось секунды за две.

Т.е. основное время съедается имнно постобратокой этого миллиона записей.

Добавлено через 2 минуты и 3 секунды
Rigel, а колическтво секций это нечто фиксированное, или у каждой книги оно разное?


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.