說我有一個3列和成千上萬的記錄,像這樣的表:MySQL的優化當不是所有的列索引
id # primary key
name # indexed
gender # not indexed
而且我想找到「命名的亞歷克斯所有的男性」,即一個特定的名稱和具體的性別。
難道這裏不夠好(select * from people where name='alex' and gender=2
)嗎?還是有更優化的方式,比如名稱上的子查詢?
說我有一個3列和成千上萬的記錄,像這樣的表:MySQL的優化當不是所有的列索引
id # primary key
name # indexed
gender # not indexed
而且我想找到「命名的亞歷克斯所有的男性」,即一個特定的名稱和具體的性別。
難道這裏不夠好(select * from people where name='alex' and gender=2
)嗎?還是有更優化的方式,比如名稱上的子查詢?
假設您沒有數千條記錄,匹配名稱,只有少數實際上是男性,name
上的索引就足夠了。一般來說,你不應該索引具有小冪的字段(只有2個可能的值意味着你將匹配50%的行,這不合理的使用索引)。
我能想到的唯一有用的例外是,如果您僅選擇名稱和性別,並且如果您將它們都放入索引中,則可以執行index-covered query
,這比按索引選擇行更快,然後從表中檢索數據。
更好的方法是有一個複合索引。
即
CREATE INDEX <some name for the index> ON <table name> (name, gender)
然後WHERE
子句可以用它的名稱和性別兩者。
如果創建索引不是選項,或者表中有大量數據(或者即使有索引,但仍想加快速度),它通常會對根據您分組在一起的數據對錶格重新排序。
我有一個查詢工作,爲我的部門一起獲得KPI,即使一切都很好地索引,被拉的數據仍然通過一些表演。這意味着很多光盤訪問,而查詢將所有正確的行聚合在一起。我使用alter table tableName order by column1, column2;
對錶格進行了重新排序,查詢花費了大約15秒時間返回了3以下的數據。因此,數據的物理收集可能會產生重大影響 - 即使表格被索引並且數據庫確切知道從何處獲取數據。排列數據以便數據庫更容易地獲取所需的所有內容,從而提高性能。
雖然只對MyISAM表有用,並且發生在某個時間點;後續的插入/更新會慢慢將此順序碎片化。 – TerryE 2012-07-27 09:04:26
可能有用,但試圖避免額外索引的開銷。如果只有少數人匹配任何名字,這似乎是過分的。 – mahemoff 2012-07-27 12:50:02
@mahemoff - 硬盤相當便宜。此外,如果您仔細選擇了這些索引,它們也可以用於其他查詢。 – 2012-07-27 12:57:41
儘管如此,如果達到所有索引都不適合單個磁盤的程度,集羣的成本和複雜性仍然很高。 – mahemoff 2012-07-27 13:01:26