Mysql
按指定列對錶進行預排序
我有一張桌子,我總是通過訂購一列來獲取數據。就我而言,我按
datenum
. 但是,由於排序,選擇非常慢。是否可以在之後訂購桌子
datenum
。此列被定義為唯一的。如果定義為索引,選擇會更快嗎?
- 表沒有自然的、隱含的或內在的排序
- 任何訂單僅由最外層的 ORDER BY 保證
如果這很慢,那麼您可以
- 使索引覆蓋(唯一約束已經是索引)
- 使其成為聚集索引(其性質涵蓋)
可以對錶執行 ORDER BY。
ALTER TABLE … ORDER BY {columns} ;
根據 MySQL 文件
- ORDER BY 使您能夠創建具有特定順序的行的新表。請注意,插入和刪除後,表不會保持此順序。此選項主要在您知道大部分時間以特定順序查詢行時很有用。通過在對錶進行重大更改後使用此選項,您可能可以獲得更高的性能。在某些情況下,如果表按您稍後要對其排序的列進行排序,則可能會使 MySQL 更容易排序。
- ORDER BY 語法允許為排序指定一個或多個列名,每個列名可選地後跟 ASC 或 DESC 以分別指示升序或降序排序。預設為升序。只允許列名作為排序條件;不允許任意表達。
- ORDER BY 對於包含使用者定義的聚集索引(PRIMARY KEY 或 NOT NULL UNIQUE 索引)的 InnoDB 表沒有意義。如果存在這樣的索引,InnoDB 總是根據這樣的索引對錶行進行排序。
- 注意:在分區表上使用時,ALTER TABLE … ORDER BY 僅對每個分區內的行進行排序。
由於 InnoDB 執行雙索引查找(一個針對 PRIMARY KEY,然後一個針對內部聚集索引gen_clust_index),在 InnoDB 表上執行 ORDER BY 確實不會為您帶來任何性能提升。
恕我直言,如果 PRIMARY KEY 有一些令人討厭的東西,比如 8 列
- 對於 MyISAM,您將獲得出色的查找和範圍搜尋性能
- 對於 InnoDB,您充其量只會得到非常邊緣的結果(如果有的話)。
注意:理論上,如果您執行以下操作,您可能會在 InnoDB 表(稱為 mytable)中看到非常非常小的性能差異:
CREATE TABLE mytable_new LIKE mytable; INSERT INTO mytable_new SELECT * FROM mytable ORDER BY {primary-key columns}; ALTER TABLE mytable RENAME mytable_old; ALTER TABLE mytable_new RENAME mytable;
這將按 rowid 順序和主鍵順序對 gen_clust_index(內部集群索引)進行排序。但是,執行這種 rowid 的內部排序就像把鉛變成金一樣。時間、精力和能量處理遠遠超過了任何看似購買但從未實現的性能優勢,因為每個主鍵查找也會導致 rowid 查找。長話短說:除非您只使用 MyISAM,否則不要這樣做。
這是我對 PRIMARY KEY 中的列使用 ORDER BY 的標準
- PRIMARY KEY 中有 4 列或更多列
- 對於具有 n 列的 PRIMARY KEY,列 1 .. n-1 在 WHERE 和 GROUP BY 子句中應該是靜態的,而列 n 將用作查詢中的範圍列
- 僅使用 MyISAM 儲存引擎!!!
警告
我提到 8 列 PRIMARY KEY 的原因是什麼?我以前的雇主每月從外部供應商那裡發送數十 GB 的只讀數據。我在那裡學習了 ALTER TABLE…ORDER BY 並將它用於那些 MyISAM 表。由於針對 PRIMARY KEY 進行了很多範圍查詢,因此查詢時間令所有人震驚,包括我自己。