|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
27.12.2012, 09:53 | #1 |
Пользователь
Регистрация: 15.01.2012
Сообщений: 67
|
Поиск узких мест в запросе (производительностьd MySQL)
Значит так. Сделал базу, запросы, все дела. Проиндексировал основные поля (все внутренние и внешние ключи, а также даты, так как по ним делаю выборки).
Один из больших запросов у меня ускорился с 250 до 1 секунды. Второй тоже стал побыстрее, но 500 секунд, даже по сравнению с тем, что было... Проблемный запрос в следующем сообщении, тут не лезет - большой. Я грешу на то, что у меня используются подзапросы, в которых mysql не может использовать индекс: Код:
Код:
Единственный способ обрезать эту таблицу - это выборка по полю PAYMENT_ID, у которого пеймента связь многие ко многим с TAKEOUT_ID. То есть, пока я не вижу возможности не использовать IN. |
27.12.2012, 09:54 | #2 |
Пользователь
Регистрация: 15.01.2012
Сообщений: 67
|
Сам запрос:
Код:
|
27.12.2012, 10:40 | #3 | |
Пользователь
Регистрация: 15.01.2012
Сообщений: 67
|
Ну в общем как обычно на свои темы отвечаю сам.
Грешил я на те подзапросы правильно, в них вся проблема. Используйте джоины вместо инов, посоны. Подзапросы вида Цитата:
|
|
27.12.2012, 10:48 | #4 | |
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
Для начала опробовать вместо IN такой вариант
Код:
Цитата:
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
|
|
28.12.2012, 10:18 | #5 |
Пользователь
Регистрация: 15.01.2012
Сообщений: 67
|
Ладно, тогда другой вопрос, что-то я сам не додумался.
Код:
Когда убираю "OR '%' = '1'" - всё становится на место, срабатывают индексы, оптимизации, выполняется за миллисекунды. А так - несколько секунд. Я интерпретирую это так, что все остальне таблицы ограничиваются по индексированным ключам в связках и в условии, а таблица PAYOUT как будто бы ничем напрямую не ограничивается, поэтому mysql выполняет проверку равентсва '%' = '1' для каждой строки в таблице. Однако, во-первых, ежу понятно, что данное равенство не может быть разным для разных строк - достаточно вычислить его один раз. Во-вторых, на более простом запросе, например SELECT * FROM PAYOUT WHERE (ID = '1' OR '%' = '1') mysql вполне разбирается в ситуации и не проверяет все строки. Соответственно, вопрос в том, есть ли какие-то директивы, чтобы указать субду, как именно надо оптимизировать запрос, либо способ иначе описать конструкцию (ID = '1' OR '%' = '1'), так, чтобы она не смущала базу данных? |
28.12.2012, 10:44 | #6 |
Старожил
Регистрация: 09.01.2008
Сообщений: 26,229
|
а не вариант засунуть тот запрос, который, по вашим словам корректно работает, в подзапрос (если, конечно, MySQL это позволяет!)
я имею в виду: Код:
p.s. я из личного опыта давно сделал умозаключение (скорее всего, ошибочное в общем случае, но на практике часто очень полезное) - любое использование OR в запросе - это сразу провал в производительности запроса |
28.12.2012, 11:19 | #7 | ||
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
Цитата:
Цитата:
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
|
||
28.12.2012, 15:00 | #8 | |
Пользователь
Регистрация: 15.01.2012
Сообщений: 67
|
В чём тут залепуха? Что код всегда один и тот же? Это как раз нормальный подход - добавить одно элементарное условие в запрос и не трогать его, вместо того, чтобы городить всякие если-то ещё и в коде программы.
Если в условии с OR есть равенство с константами типа 1 = 1, то вполне очевидно, что весь блок всегда TRUE и его можно вовсе исключить из запроса. А если FALSE, то само равенство также можно исключить из запроса. Если субда этого не умеет, значит такая замечательная субда. В оракле никогда проблем не возникало, хотя там делал выборки из таблиц с сотнями тысяч записей и кучей джоинов и не одним таким условием вида '%' = '%'. Цитата:
Последний раз редактировалось yaapelsinko; 28.12.2012 в 15:02. |
|
28.12.2012, 16:17 | #9 | |
Старожил
Регистрация: 17.11.2010
Сообщений: 18,922
|
Цитата:
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
|
|
29.12.2012, 03:31 | #10 |
Пользователь
Регистрация: 15.01.2012
Сообщений: 67
|
Главное при этом помнить, о чём идёт речь - о том, можно ли какими-либо специальными директивами или особой структурой запроса избежать этого бага (а тут явно баг оптимизатора) и чётко указать, для какой таблицы какая проверка должна выполняться.
А не о преимуществах каких-то разных вещей или подходов в программировании. |
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Переменные в mysql запросе | Redline 117 | C/C++ Базы данных | 2 | 12.06.2012 13:28 |
Paradox. Поиск свободных мест на автобус. | Ti_pain) | SQL, базы данных | 0 | 10.12.2011 12:38 |
MySql запрос в запросе | Gorychev | SQL, базы данных | 0 | 29.07.2010 21:21 |
MySQL-нужна помощь в запросе | Stema | SQL, базы данных | 9 | 18.10.2008 19:51 |
Поиск узких мест | RomanIgorevi4 | Общие вопросы C/C++ | 8 | 08.07.2008 18:24 |