Внутреннее соединение занимает слишком много времени, как я могу его ускорить?

#sql

#sql

Вопрос:

у меня следующая ситуация:

у меня была таблица с уникальным ограничением полей serie_id и user_id, я удалил ее, чтобы попробовать что-то, и теперь у меня есть дублированные строки (т. Е. Две или более строк, где пара user_id И serie_id равны)

при попытке просмотреть дублированные строки я использую это

 SELECT t1.id 
FROM table_A t1 
INNER JOIN table_A t2 
ON t1.serie_id = t2.serie_id AND t1.user_id = t2.user_id 
WHERE t1.id < t2.id
  

но в таблице МНОГО данных, поэтому это занимает слишком много времени. Есть ли способ оптимизировать его или ускорить?

отредактировано: теперь я использую этот запрос, чтобы получить все идентификаторы дублированных строк,

 SELECT id
FROM   table_A a
WHERE  EXISTS (SELECT 1
               FROM   table_A b
               WHERE  a.user_id = b.user_id AND a.serie_id = b.serie_id
               HAVING Count(*) > 1) 
Order by id desc
  

это также занимает много времени, более получаса.

Также я хочу сохранить для каждой дублированной записи исходную, как я могу исключить ее из результатов этого запроса?

Я не могу использовать OVER или NUMBER_ROW, как я видел в других комментариях, моя версия этого не позволяет

Пример данных:

 id       serie_id         user_id
1          100              111
2          100              222
3          100              222
4          58               222
5          100              115
6          100              222
  

Я хочу удалить первые две строки, соответствующие паре user_id:100 — serie_id= 222
таким образом, результат будет:

 id       serie_id         user_id
1          100              111
4          58               222
5          100              115
6          100              222
  

Комментарии:

1. Пожалуйста, предоставьте образцы данных, желаемые результаты и соответствующий тег базы данных.

2. Опубликуйте схему таблицы, включая все типы столбцов и индексы. и грамматика: если что-то занимает слишком много времени, вы не хотите «замедлять это»; вы хотите ускорить это .

Ответ №1:

Вы должны определить индекс для полей, которые вы хотите использовать во внутреннем соединении. А также для полей, которые вы хотите использовать в кластерах WHERE.

Вы можете включить «Включить фактическую плоскость выполнения» в SQLServer Managmenet Studio. SQL предлагает вам советы по повышению производительности запросов.

Ответ №2:

Чтобы увидеть повторяющуюся пару, вы можете использовать такой запрос:

 SELECT t1.serie_id, t1.user_id, COUNT(*) CNT
FROM table_A t1 
GROUP BY t1.serie_id, t1.user_id
HAVING COUNT(*) > 1
  

И чтобы вернуть фактические строки, сохраните результат во временной таблице и присоедините его к исходной таблице, например:

 IF OBJECT_ID('tempdb.dbo.#tmp') IS NOT NULL DROP TABLE #tmp
    CREATE TABLE #tmp ( serie_id INT, user_id INT, CNT INT)

INSERT INTO #tmp( serie_id, user_id, CNT )
    SELECT t1.serie_id, t1.user_id, COUNT(*) CNT
    FROM table_A t1 
    GROUP BY t1.serie_id, t1.user_id
    HAVING COUNT(*) > 1

SELECT t1.*, 
FROM table_A t1 INNER JOIN #tmp tmp on tmp.serie_id = t1.serie_id and tmp.user_id = t1.user_id 
  

В любом случае, индекс по serie_id, user_id столбцам должен помочь.

Комментарии:

1. Я использую это, чтобы вернуть идентификаторы дублированных строк, но я хочу сохранить один из них, удалив остальные ВЫБЕРИТЕ идентификатор ИЗ таблицы_a a, ГДЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ таблицы_a b, ГДЕ a.user_id = b.user_id И a.serie_id = b.serie_id, ИМЕЮЩИЙ Count(*)> 1) Порядок по идентификатору desc

2. У меня уже есть индексы как для serie_id, так и для user_id