Postgresql

需要考慮是否索引一個複雜的查詢 Postgres sql

  • July 13, 2022

這是查詢範例

放置索引需要考慮哪一列?每個索引可以應用每列或多列的最佳索引是什麼?

我的問題是當我執行這個查詢時需要很長時間才能完成

是查詢或索引的複雜性嗎?

蒂亞!

SELECT
a.id
a.name AS name
CASE
  WHEN a.status IS NULL THEN '1111'
  WHEN a.status = '2222' THEN '3333'
  WHEN a.status = '4444' THEN '5555'
  ELSE a.status
END AS status,
a.updated_at
FROM a
LEFT JOIN b ON a.request_id = b.request_id
LEFT JOIN (
  SELECT 
   DISTINCT ON (id) id,
   name
  FROM
   aa
  WHERE
   updated_at BETWEEN '2022-05-01 00:00:00' AND '2022-05-31 23:59:59'
   AND id IN (
     SELECT id 
     FROM a
     WHERE 
     updated_at BETWEEN '2022-05-01 00:00:00' AND '2022-05-31 23:59:59'
     AND status NOT IN ('6666', '7777', '8888')
     AND id LIKE '%%'
                )
)
WHERE 
a.updated_at BETWEEN '2022-05-01 00:00:00' AND '2022-05-31 23:59:59'
AND status NOT IN ('6666', '7777', '8888')
AND id LIKE '%%'

UNION

SELECT
z.id
z.name AS name
CASE
  WHEN z.status IS NULL THEN '1111'
  WHEN z.status = '2222' THEN '3333'
  WHEN z.status = '4444' THEN '5555'
  ELSE z.status
END AS status,
z.updated_at
FROM z
LEFT JOIN zb ON z.request_id = zb.request_id
LEFT JOIN (
  SELECT 
   DISTINCT ON (id) id,
   name
  FROM
   zz
  WHERE
   updated_at BETWEEN '2022-05-01 00:00:00' AND '2022-05-31 23:59:59'
   AND id IN (
     SELECT id 
     FROM z
     WHERE 
     updated_at BETWEEN '2022-05-01 00:00:00' AND '2022-05-31 23:59:59'
     AND status NOT IN ('6666', '7777', '8888')
     AND id LIKE '%%'
                )
)
WHERE 
z.updated_at BETWEEN '2022-05-01 00:00:00' AND '2022-05-31 23:59:59'
AND status NOT IN ('6666', '7777', '8888')
AND id LIKE '%%'

需要注意的一點是,聚集索引應該有一個唯一鍵(我推薦的標識列)作為第一列。基本上,它可以幫助您在索引末尾插入數據,並且不會導致大量磁碟 IO 和頁面拆分。

其次,如果您在數據上創建其他索引並且它們構造巧妙,它們將被重用。

例如,假設您在三列上搜尋表格

州、縣、郵編。

you sometimes search by state only.
you sometimes search by state and county.
you frequently search by state, county, zip.

然後是州、縣、郵編的索引。將在所有這三個搜尋中使用。

如果您僅通過 zip 進行大量搜尋,則上述索引將不會被使用(無論如何,SQL Server 都不會使用),因為 zip 是該索引的第三部分,並且查詢優化器不會將該索引視為有用。

然後,您可以僅在 Zip 上創建將在此實例中使用的索引。

順便說一句,我們可以利用這樣一個事實,即使用多列索引,第一個索引列始終可用於搜尋,當您僅按“狀態”搜尋時,它是有效的,但不如“狀態”上的單列索引高效'

我想您正在尋找的答案是它取決於您經常使用的查詢的 where 子句以及您的 group by。

這篇文章會有很大幫助。:-)

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