2012-07-27 23 views
2

說我有一個3列和成千上萬的記錄,像這樣的表:MySQL的優化當不是所有的列索引

id # primary key 
name # indexed 
gender # not indexed 

而且我想找到「命名的亞歷克斯所有的男性」,即一個特定的名稱和具體的性別。

難道這裏不夠好(select * from people where name='alex' and gender=2)嗎?還是有更優化的方式,比如名稱上的子查詢?

回答

1

假設您沒有數千條記錄,匹配​​名稱,只有少數實際上是男性,name上的索引就足夠了。一般來說,你不應該索引具有小冪的字段(只有2個可能的值意味着你將匹配50%的行,這不合理的使用索引)。

我能想到的唯一有用的例外是,如果您僅選擇名稱和性別,並且如果您將它們都放入索引中,則可以執行index-covered query,這比按索引選擇行更快,然後從表中檢索數據。

0

更好的方法是有一個複合索引。

CREATE INDEX <some name for the index> ON <table name> (name, gender) 

然後WHERE子句可以用它的名稱和性別兩者。

+0

可能有用,但試圖避免額外索引的開銷。如果只有少數人匹配任何名字,這似乎是過分的。 – mahemoff 2012-07-27 12:50:02

+0

@mahemoff - 硬盤相當便宜。此外,如果您仔細選擇了這些索引,它們也可以用於其他查詢。 – 2012-07-27 12:57:41

+0

儘管如此,如果達到所有索引都不適合單個磁盤的程度,集羣的成本和複雜性仍然很高。 – mahemoff 2012-07-27 13:01:26

1

如果創建索引不是選項,或者表中有大量數據(或者即使有索引,但仍想加快速度),它通常會對根據您分組在一起的數據對錶格重新排序。

我有一個查詢工作,爲我的部門一起獲得KPI,即使一切都很好地索引,被拉的數據仍然通過一些表演。這意味着很多光盤訪問,而查詢將所有正確的行聚合在一起。我使用alter table tableName order by column1, column2;對錶格進行了重新排序,查詢花費了大約15秒時間返回了3以下的數據。因此,數據的物理收集可能會產生重大影響 - 即使表格被索引並且數據庫確切知道從何處獲取數據。排列數據以便數據庫更容易地獲取所需的所有內容,從而提高性能。

+0

雖然只對MyISAM表有用,並且發生在某個時間點;後續的插入/更新會慢慢將此順序碎片化。 – TerryE 2012-07-27 09:04:26