簡體   English   中英

創建 SQL 索引以提高速度

[英]Create SQL indexes for speed

我正在從帶有transaction_id列和last_modified_date列的表中刪除重復項(請參閱下面的查詢)。 這個想法是每個transaction_id應該有一個記錄,所以我需要刪除重復項,保留給定transaction_id的最后修改記錄。

查詢有效,但速度很慢。

問題是:我應該創建什么索引來加快查詢執行時間?

With CTE_Duplicates as
(
   select 
       transaction_id, 
       row_number() over (partition by transaction_id order by last_modified_date desc) rownumber 
   from 
       TRANSACTIONS 
)  
delete from CTE_Duplicates 
where rownumber != 1;  

謝謝!

瓦爾德

對於您的查詢版本:

With CTE_Duplicates as (
    select t.*,
           row_number() over (partition by transaction_id order by last_modified_date desc) as rownumber
    from TRANSACTIONS
   )
delete from CTE_Duplicates
    where rownumber > 1;

您需要(transaction_id, last_modified_date desc)上的索引。 但是,使用相同的索引,將查詢表述為以下語句可能會更快:

delete t from transactions t
    where t.last_modified_date = (select max(t2.last_modified_date)
                                  from transactions t2
                                  where t2.transaction_id = t.transaction_id
                                 );

盡管如此,如果要刪除許多行(“許多”甚至可能是百分之幾),您的查詢將非常昂貴。 在這種情況下,臨時表解決方案可能更好:

select t.*
into temp_transactions
from transactions t
where t.last_modified_date = (select max(t2.last_modified_date)
                              from transactions t2
                              where t2.transaction_id = t.transaction_id
                             );

truncation table temp_transactions;  -- backup first!

insert into transactions
    select *
    from temp_transactions;

當然,如果您有標識列或在表上設置值的觸發器,則邏輯會更加復雜。

對於此查詢:

with CTE_Duplicates as (
    select 
        transaction_id, 
        row_number() 
            over(partition by transaction_id order by last_modified_date desc ) rownumber 
    from TRANSACTIONS 
) 
delete from CTE_Duplicates where rownumber!=1;

您只需要(transaction_id, last_modified_date)上的復合索引。

create index idx_transactions_dup on transactions(transaction_id, last_modified_date);

無論您選擇哪種解決方案,您能做的最好的事情可能就是在 (transaction_id, last_modified_date) 上添加復合索引。 這樣做之后,我會在窗口函數上使用聚合函數(考慮到它們的分區和排序能力,我不確定它們會如何利用理想的索引)......

; WITH keepers AS (
   SELECT transaction_id, MAX(last_modified_date) AS last_modified_date
   FROM transactions 
   GROUP BY transaction_id
)
DELETE t 
FROM transactions AS t
LEFT JOIN keepers AS k
   ON t.transaction_id = k.transaction_id 
   AND t.last_modified_date = k.last_modified_date
WHERE k.transaction_id IS NULL
;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM