Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: тяжелый запрос?
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » тяжелый запрос?

Страниц (1): [1]
 

1. Еугений - 18 Октября, 2016 - 18:18:15 - перейти к сообщению
Всем привет, есть таблица textbooks размером 1.1 гигабайт
К ней обращаются по такому запросу
select id, title from texbooks where book_id = 112233 and status = 1 order by id desc

индекс стоит на поле book_id.

В последнее время бд начала нехило тормозить, ищу проблему, а этот запрос начал тормозить 1-2 секунды выполнения, вот и решил его исследовать.

должен ли такой запрос выполнятся долго? можно ли как то улучшить запрос?

я думаю, что этот запрос не должен выполнятся долго. вроде, бд должна сначала должна вытащить записи по запросу where book_id = 112233 т.к. на нем индекс, то есть быстро, и по полученным записям сделать вторую выборку status = 1 и их отсортировать order by.

или status = 1 заставит БД пройтись по всей таблице??
БД mysql
2. Мелкий - 18 Октября, 2016 - 18:52:25 - перейти к сообщению
explain?
Сколько в таблице записей с таким book_id? Сколько из них с status = 1?
3. Еугений - 18 Октября, 2016 - 18:59:57 - перейти к сообщению
Мелкий пишет:
explain?Сколько в таблице записей с таким book_id?

По разному. в textbooks хранятся главы книг с текстом, у книги может быть одна глава, а то и 50. Ну в среднем 15 записей по определенному book_id/
Мелкий пишет:
Сколько из них с status = 1?

Я перепутал, status = 0. Это означает глава не удалена, удаленных глав почти нет, но изредка главы удаляются, поэтому и запрос такой. Так что, очень мало. в 99% случаев status = 0, 1% status = 0.
(Добавление)
может быть проблема в том, что я неправильно организовал все...

Таблица textbooks содержит столбцы id, title (название главы), text_of_chapter (сам текст главы, иногда там хранится 1мб текста),status.

Запросом, который я привел выше, я просто вытаскиваю оглавление (нужны только title), но не текст. Наверно надо будет эту таблицу разбить на две таблицы: главы; текст главы.
4. Мелкий - 18 Октября, 2016 - 20:52:04 - перейти к сообщению
Адекватно.
Производительность доступа к случайной главе по прямому id нормальная?
Что говорит профилировщик, на что субд затрачивает время? https://dev[dot]mysql[dot]com/doc/refman[dot][dot][dot]how-profile[dot]html И там же, профайлер io.
5. Еугений - 18 Октября, 2016 - 21:20:41 - перейти к сообщению
Мелкий пишет:
Адекватно.
Производительность доступа к случайной главе по прямому id нормальная?
Что говорит профилировщик, на что субд затрачивает время? https://dev[dot]mysql[dot]com/doc/refman[dot][dot][dot]how-profile[dot]html И там же, профайлер io.

в phpmyadmin использовал Profiler
по id запрос выполняется быстро.
sorting result 1.9 s
Вообщем, проверил 10 запросов, затраты на sorting result составляют почти все время (от 0.1 сек до 2 сек). Почему же так долго, может потому большой объем извлекается? некоторые главы в сумме составляют мегабайт текста.
наверно придется отказаться от order by, а сортировку делать средствами php.
есть ли способы это улучшить?
6. Мелкий - 18 Октября, 2016 - 21:56:40 - перейти к сообщению
Это с text полем или без него? В теме уже фигурировали оба запроса, но между ними серьёзная разница.
Для text ещё объяснимо, сортировка датасета с text - это всегда дисковая сортировка. А без него - запрос должен нормально жить.

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id, title FROM texbooks WHERE book_id = 112233 AND STATUS = 1 ORDER BY id DESC

Должен шевелиться адекватно. И если шевелится адекватно, то обходной путь есть и для вычитывания самих текстов:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id, name, ltext FROM (
  2.     SELECT id FROM texbooks WHERE book_id = 112233 AND STATUS = 1 ORDER BY id DESC
  3. ) t STRAIGHT_JOIN texbooks USING(id)
7. Еугений - 18 Октября, 2016 - 22:16:46 - перейти к сообщению
Мелкий пишет:
Это с text полем или без него? В теме уже фигурировали оба запроса, но между ними серьёзная разница.
Для text ещё объяснимо, сортировка датасета с text - это всегда дисковая сортировка. А без него - запрос должен нормально жить.

ох, точно, тестировал на select * from..., совсем забыл про поля. сам текст не нужен. Стало 0.2 - 0.4 сек - и это тоже на сортировку все время ушло.
Странно, утром и днем наблюдал, что почему то эти запросы были очень долгие 1-2 секунды, и пользователи в последнее время стали жаловаться, что сайт часто начал висеть. Буду искать далее слабые места, спасибо, что помогли, профайлер - вещь, не знал о нем Улыбка
8. Мелкий - 18 Октября, 2016 - 22:28:33 - перейти к сообщению
Можно воткнуть индекс book_id & status. С учётом неявной ссылка на PK в innodb получится отличный index scan, включая сортировку.

 

Powered by ExBB FM 1.0 RC1