如何为MySQL表添加索引?
我有一个有大约150,000行数据的非常大的MySQL表。 目前,当我尝试和运行
SELECT * FROM table WHERE id = '1';
代码运行良好,因为ID字段是主索引。 但是,最近为了项目的发展,我不得不在另一个领域search数据库。 例如
SELECT * FROM table WHERE product_id = '1';
此字段以前没有索引,但是,我已经将其添加为索引,但是当我尝试运行上述查询时,结果是非常缓慢的。 EXPLAIN查询显示,当我已经添加一个product_id字段时,没有索引,并且查询从20分钟到30分钟之间的任何地方返回一行。
我完整的EXPLAIN结果是:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+----------------------+------+---------+------+------+------------------+ | 1 | SIMPLE | table | ALL | NULL | NULL | NULL | NULL | 157211 | Using where | +----+-------------+-------+------+----------------------+------+---------+------+------+------------------+
注意到我刚刚看过,ID字段存储为INT,而PRODUCT_ID字段存储为VARCHAR可能会有所帮助。 这可能是问题的根源吗?
ALTER TABLE `table` ADD INDEX `product_id` (`product_id`)
不要把integer
与MySQL中的strings
进行比较 如果id
是int
,请删除引号。
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);
你可以使用这个语法来添加索引并控制索引的种类(HASH或者BTREE)
create index your_index_name on your_table_name(your_column_name) using HASH; or create index your_index_name on your_table_name(your_column_name) using BTREE;
您可以在这里了解BTREE和HASH索引之间的区别: http : //dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html
值得注意的是,多个字段索引可以大大提高查询性能。 所以在上面的例子中,我们假设ProductID是唯一的查找字段,但查询说产品ID = 1和类别= 7然后多列索引帮助。 这是通过以下方式实现的:
ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)
另外索引应该匹配查询字段的顺序。 在我的扩展示例中,索引应该是(ProductID,Category)而不是其他方式。
可以添加两种types的索引:当你定义一个主键的时候,MySQL会默认把它作为索引
说明
主键为索引
考虑你有一个TBL_STUDENT表,你需要STUDENT_ID作为主键:
ALTER TABLE `tbl_student` ADD PRIMARY KEY (`student_id`)
上面的语句添加了一个主键,这意味着索引值必须是唯一的,不能为NULL。
指定索引名称
ALTER TABLE `tbl_student` ADD INDEX student_index (`student_id`)
上面的语句将创build一个具有student_index
名称的普通索引。
创build独特的索引
ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)
这里, student_unique_index
是分配给STUDENT_ID的索引名称,并创build一个索引,其值必须是唯一的(这里可以接受null)。
全文选项
ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)
上面的语句将创build带有student_fulltext_index
的Fulltext索引名称,为此您需要MyISAM Mysql引擎。
如何删除索引?
DROP INDEX `student_index` ON `tbl_student`
如何检查可用的索引?
SHOW INDEX FROM `tbl_student`
你说你有一个索引,否则解释说。 但是,如果你真的这样做了,那么该如何继续:
如果你在列上有一个索引,并且MySQL决定不使用它,可能是因为:
- MySQL认为查询中有另一个索引更适合使用,并且只能使用一个索引。 如果解决scheme的正常检索方式是多于一列的值,那么解决scheme通常是跨多列的索引。
- MySQL决定有很多匹配的行,并认为一个tablescan可能更快。 如果情况并非如此,有时一个
ANALYZE TABLE
帮助。 - 在更复杂的查询中,它决定不使用它在查询计划中基于非常聪明的深思熟虑的巫术,由于某种原因,这只是不符合您当前的要求。
在(2)或(3)的情况下,你可以通过index hint sytax来让MySQL使用索引,但是如果你这样做的话,一定要运行一些testing,以确定它是否实际上提高了使用索引的性能。