Простые запросы MySQL требуют много времени для вычисления - PullRequest
7 голосов
/ 15 ноября 2011

Я только изучаю MySQL, и у меня есть проблема.

Иногда для различных запросов MySQL начинает вычислять при 100% загрузке ЦП в течение 15-20 секунд и затем возвращает результат, обычно говоря:

Запрос занял 0,1780 сек.

Это происходит по очень простым запросам. Например, этот запрос занял 0,36 секунды.

(SELECT DISTINCT a1.actor 
 FROM   actors AS a1, 
        actors AS a2 
 WHERE  a1.title = a2.title 
        AND a1.YEAR = a2.YEAR 
        AND a1.actor = a2.actor 
        AND a1.character_name <> a2.character_name) 

Листинг таблицы (7000 строк) занял 0,001 секунды.

С другой стороны, когда я просто хочу объединить эти два, MySQL сходит с ума и начинает вычислять в течение 30 секунд, а затем, наконец, возвращает: Query took 0.1800 sec)

SELECT actor 
FROM   actors 
WHERE  actor NOT IN (SELECT DISTINCT a1.actor 
                     FROM   actors AS a1, 
                            actors AS a2 
                     WHERE  a1.title = a2.title 
                            AND a1.YEAR = a2.YEAR 
                            AND a1.actor = a2.actor 
                            AND a1.character_name <> a2.character_name) 

Почему это происходит?

Вот другой пример. Этот запрос занимает около 2 секунд и сообщает 0,5

SELECT DISTINCT a1.character_name 
FROM   (actors AS a1 
        NATURAL JOIN movies AS m1), 
       (actors AS a2 
        NATURAL JOIN movies AS m2) 
WHERE  a1.character_name = a2.character_name 
       AND ( m1.title <> m2.title 
              OR ( m1.title = m2.title 
                   AND m1.year <> m2.year ) ) 
       AND m1.country <> m2.country 

С другой стороны, этот запрос занимает 15-20 секунд, процессор 100%, но сообщает 0,3 секунды. (Единственное отличие - это скобка после AND (....)

SELECT DISTINCT a1.character_name 
FROM   (actors AS a1 
        NATURAL JOIN movies AS m1), 
       (actors AS a2 
        NATURAL JOIN movies AS m2) 
WHERE  a1.character_name = a2.character_name 
       AND m1.title <> m2.title 
        OR ( m1.title = m2.title 
             AND m1.YEAR <> m2.YEAR ) 
           AND m1.country <> m2.country 

Я использую phpMyAdmin и последнюю версию XAMPP для тестирования.

Обновление:

Неправильное время запроса, похоже, связано с phpMyAdmin, в командной строке я получаю следующее время:

  • 1-й запрос: MySQL: 0,36 с - PostgreSQL: 0,37 с
  • 2-й запрос: MySQL: 43 с - PostgreSQL: 0,42 с
  • 3-й запрос: MySQL: 4,86 ​​с - PostgreSQL: 0,05 с
  • 4-й запрос: MySQL: 1 мин 5 с - PostgreSQL: 15 секунд

Итак, у меня есть ответ на вопрос, почему время запроса сообщалось неправильно (ошибка в phpMyAdmin или XAMPP), меня интересует почему такие похожие запросы имеют такую ​​большую разницу во времени выполнения? 1064 * Обновление 2:

Просто для полноты я тоже провел тестирование с PostgreSQL

Ответы [ 4 ]

4 голосов
/ 15 ноября 2011

Вы пробовали тестировать свои запросы с приглашением mysql cmd ??? Если проблема не устранена, возможно, проблема связана с mysql, но если проблема решена, я думаю, у вас проблема с phpmyadmin. Итак, дайте мне знать, сохраняется ли ваша проблема после того, как вы попытаетесь выполнить запросы с помощью команды mysql cmd.

1 голос
/ 15 ноября 2011
SELECT actor 
FROM   actors 
WHERE  actor NOT IN (SELECT DISTINCT a1.actor 
                     FROM   actors AS a1, 
                            actors AS a2 
                     WHERE  a1.title = a2.title 
                            AND a1.YEAR = a2.YEAR 
                            AND a1.actor = a2.actor 
                            AND a1.character_name <> a2.character_name)

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

select   actor
from     actors
group by actor, year, title
having   count(character_name) = 1

Тем не менее, я знаю, что ваш вопрос не был связан с вашими возможностями написания SQL, и вы просто пытаетесь выяснить, почему странное поведение MySql.Я предполагаю, что это исключает определенные вещи из времени исполнения.Например, когда Google сообщает, что для получения результатов потребовалось 0,09 секунды, но вы знаете, что 10 секунд ожидали загрузки страницы.Google не учел те 9,91 секунды, которые потребовалось, чтобы добраться от своего сервера до вашего компьютера ... просто, сколько времени им потребовалось для запроса данных.

Это определенно выглядит как явная проблемачто MySql должен учитывать, хотя, в отличие от Google, который не может знать другую часть уравнения, MySql должен иметь возможность включить весь процесс в расчет времени.

1 голос
/ 15 ноября 2011

Изменить это (Ваш первый запрос)

SELECT DISTINCT a1.actor 
FROM   actors AS a1, 
actors AS a2 
WHERE  a1.title = a2.title 
AND a1.YEAR = a2.YEAR 
AND a1.actor = a2.actor 
AND a1.character_name <> a2.character_name) 

к этому:

SELECT *
FROM actors a1
JOIN actors a2 ON (a1.title = a2.title AND a1.actor = a2.actor)
GROUP BY a1.actor
HAVING a1.character_name <> a2.character_name

и используйте тот же стиль для остальных, также убедитесь, что у вас есть правильные индексы в ваших таблицах.

0 голосов
/ 15 ноября 2011

Попробуйте использовать EXPLAIN для профилирования ваших запросов.И мой совет - не использовать подзапросы.

...