У меня есть пара дубликатов в базе данных, которые я хочу проверить, поэтому, что я сделал, чтобы увидеть, какие дубликаты, я сделал это:
SELECT relevant_field
FROM some_table
GROUP BY relevant_field
HAVING COUNT(*) > 1
Таким образом, я получу все строки с релевантным полем, встречающимся более одного раза. Этот запрос занимает миллисекунды для выполнения.
Теперь я хотел проверить каждый из дубликатов, поэтому я решил выбрать каждую строку в some_table с релевантным полем в приведенном выше запросе, поэтому я сделал так:
SELECT *
FROM some_table
WHERE relevant_field IN
(
SELECT relevant_field
FROM some_table
GROUP BY relevant_field
HAVING COUNT(*) > 1
)
Это оказывается очень медленно по какой-то причине (это занимает несколько минут). Что именно здесь происходит, чтобы сделать это так медленно? релевантное поле индексируется.
В конце концов я попытался создать представление «temp_view» из первого запроса (SELECT relevant_field FROM some_table GROUP BY relevant_field HAVING COUNT(*) > 1)
, а затем вместо этого создать свой второй запрос:
SELECT *
FROM some_table
WHERE relevant_field IN
(
SELECT relevant_field
FROM temp_view
)
И это работает просто отлично. MySQL делает это за несколько миллисекунд.
Здесь есть эксперты по SQL, которые могут объяснить, что происходит?
Ответы:
Перепишите запрос в это
Я думаю, что
st2.relevant_field
должно быть в выборе, потому что в противном случаеhaving
предложение выдаст ошибку, но я не уверен на 100%Никогда не используйте
IN
с подзапросом; это общеизвестно медленно.Только когда-либо использовать
IN
с фиксированным списком значений.Больше советов
SELECT *
выбирайте только те поля, которые вам действительно нужны.relevant_field
для ускорения равного соединения.group by
на первичном ключе.Общее решение для 90% ваших
IN (select
запросовИспользуйте этот код
источник
HAVING COUNT(*) > 1
. Обычно это быстрее в MySQL.st2.relevant_field
нетNULL
(он уже включен вON
предложение), он не изменит результат.afield
что никогда не будетnull
, понял. Спасибоgroup by
наst1.id
, а не наst1.relevant_field
.Подзапрос выполняется для каждой строки, потому что это коррелированный запрос. Можно сделать коррелированный запрос в некоррелированный запрос, выбрав все из подзапроса, например так:
Окончательный запрос будет выглядеть так:
источник
SELECT *
упаковка необходима.Подзапросы против объединений
http://www.scribd.com/doc/2546837/New-Subquery-Optimizations-In-MySQL-6
источник
Я пробовал ваш запрос в одной из моих баз данных, а также попытался переписать его как объединение с подзапросом.
Это сработало намного быстрее, попробуйте!
источник
Попробуй это
источник
Я переформатировал ваш медленный SQL-запрос с www.prettysql.net
При использовании таблицы как в запросе, так и в подзапросе вы всегда должны использовать псевдоним обоих, например так:
Это помогает?
источник
Во-первых, вы можете найти повторяющиеся строки и найти количество строк, которое используется, сколько раз, и упорядочить их по числу, как это;
после этого создайте таблицу и вставьте в нее результат.
Наконец, удалите дублирующие строки. Нет начала 0. За исключением первого номера каждой группы, удалите все дублирующие строки.
источник
иногда, когда объем данных увеличивается, mysql WHERE IN может быть довольно медленным из-за оптимизации запросов. Попробуйте использовать STRAIGHT_JOIN, чтобы сказать MySQL выполнить запрос как есть, например
но будьте осторожны: в большинстве случаев оптимизатор mysql работает довольно хорошо, поэтому я бы рекомендовал использовать его только при возникновении подобных проблем
источник
Это похоже на мой случай, когда у меня есть таблица с именем
tabel_buku_besar
. Что мне нужноИщете записи, которые есть
account_code='101.100'
вtabel_buku_besar
которых есть,companyarea='20000'
а также имеютIDR
какcurrency
Мне нужно получить все записи, у
tabel_buku_besar
которых есть account_code такой же, как на шаге 1, ноtransaction_number
на шаге 1 результатво время использования
select ... from...where....transaction_number in (select transaction_number from ....)
мой запрос выполняется очень медленно и иногда приводит к истечению времени ожидания запроса или делает мое приложение не отвечающим ...Я пробую эту комбинацию и результат ... неплохо ...
источник
Я считаю, что это наиболее эффективно для обнаружения, если значение существует, логику можно легко перевернуть, чтобы найти, если значение не существует (то есть IS NULL);
* Замените релевантное поле именем значения, которое вы хотите проверить, существует в вашей таблице.
* Замените primaryKey именем столбца первичного ключа в таблице сравнения.
источник