Oracle

Oracle - 具有大 IN 的大表

  • May 22, 2019

表學生有大約1000萬條記錄;ID 已編入索引。學生成績有 2000 萬條記錄 - student_id 已編入索引。我正在通過學生和家長之間的連接查詢大約 20,000 名學生的 ids id:

select * from students s left join grades g on s.id=g.student_id 
where (s.id IN (s1, s2... s1000)
or (s.id IN (s1001, s1002... s2000)
or (s.id IN (s.2001, s2002...s3000) 
//until s20000)

我需要將 IN 分成多個批次,因為 IN 只能獲得 1000 個或更少的值。

查詢大約需要 5 分鐘才能返回。有什麼辦法可以優化嗎?

謝謝!

數據來自外部來源

IN子句限制為 1000 個值。不要將其用於此類搜尋。

解決方法:

  • 使用 GTT(全域臨時表)
  • 將“感興趣的值”插入該 GTT
  • 修改SELECT聲明以JOIN反對 GTT。

例子

創建 GTT

create global temporary table students_gtt (
 student_id int primary key
);

將值插入 GTT

insert into students_gtt
select level
from dual
connect by level <= 50000;

並在 SELECT 語句中加入它

select
   *
from
   students       s
   left join grades         g on s.id = g.student_id
   join students_gtt   g on s.student_id = g.student_id

筆記

  1. 首先,我懷疑您的大部分時間都花在了硬解析您的查詢上。
  • 除了加入 50,000 行 GTT 之外,我將使用 22,974,957 行表並將其左外連接到 93,501,293 行表。值以秒為單位返回。
  1. 最終,您將遇到解析器的“節點”限制。
  2. GTT 方法不需要您“破解您的 SQL 語句”。

來自另一個 SQL 語句的數據?

只需在SELECT語句中包含該 SQL。

引用自:https://dba.stackexchange.com/questions/238822