如何向MySQL表添加索引?
我有一个非常大的MySQL表,大约有150000行数据。当前,当我尝试运行时如何向MySQL表添加索引?,mysql,optimization,indexing,row,Mysql,Optimization,Indexing,Row,我有一个非常大的MySQL表,大约有150000行数据。当前,当我尝试运行时 SELECT * FROM table WHERE id = '1'; 代码运行良好,因为ID字段是主索引。 然而,对于该项目的最新发展,我必须通过另一个字段搜索数据库。例如: SELECT * FROM table WHERE product_id = '1'; 此字段以前没有索引;但是,我添加了一个,所以mysql现在对字段进行索引,但是当我尝试运行上面的查询时,它运行得非常慢。EXPLAIN查询显示,当我已经
SELECT * FROM table WHERE id = '1';
代码运行良好,因为ID字段是主索引。
然而,对于该项目的最新发展,我必须通过另一个字段搜索数据库。例如:
SELECT * FROM table WHERE product_id = '1';
此字段以前没有索引;但是,我添加了一个,所以mysql现在对字段进行索引,但是当我尝试运行上面的查询时,它运行得非常慢。EXPLAIN查询显示,当我已经添加了product_id字段时,该字段没有索引,因此查询需要20分钟到30分钟的时间才能返回一行
我的全部解释结果如下:
| 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_index` (`product_id`)
永远不要将MySQL中的
整数
与字符串
进行比较。如果id
是int
,请删除引号。如果你说你有索引,解释会说没有。然而,如果你真的这样做了,这就是如何继续:
如果列上有索引,MySQL决定不使用它,可能是因为:
分析表
会有所帮助在(2)或(3)的情况下,您可以通过诱使MySQL使用索引,但如果您这样做,请务必运行一些测试,以确定按照提示使用索引是否确实提高了性能。您可以使用此语法添加索引并控制索引的类型(哈希或BTREE)
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);
或
您可以在此处了解BTREE和哈希索引之间的差异:
值得注意的是,多字段索引可以显著提高查询性能。因此,在上面的示例中,我们假设ProductID是唯一要查找的字段,但如果查询的ProductID=1和Category=7,则多列索引会有所帮助。这是通过以下方式实现的:
ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)
此外,索引应与查询字段的顺序相匹配。在我的扩展示例中,索引应该是(ProductID,Category),而不是相反。可以添加两种类型的索引:定义主键时,MySQL默认将其作为索引 解释
ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)
主键作为索引
ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)
假设您有一个tbl_student
表,并且希望student_id
作为主键:
ALTER TABLE `tbl_student` ADD PRIMARY KEY (`student_id`)
上面的语句添加了一个主键,这意味着索引值必须是唯一的,不能为NULL
指定索引名称
ALTER TABLE `tbl_student` ADD INDEX student_index (`student_id`)
上面的语句将创建一个普通索引,其名称为student\u index
name
创建唯一索引
ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)
这里,student_unique_index
是分配给student_id的索引名,并创建一个索引,其值必须是唯一的(这里可以接受null)
全文选项
ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)
上面的语句将使用student\u Fulltext\u index
创建全文索引名,您需要MyISAM Mysql引擎
如何删除索引?
DROP INDEX `student_index` ON `tbl_student`
SHOW INDEX FROM `tbl_student`
如何检查可用索引?
DROP INDEX `student_index` ON `tbl_student`
SHOW INDEX FROM `tbl_student`
更好的选择是在CREATETABLE查询期间直接添加约束(假设您有关于表的信息)
你能发布完整的
解释结果吗?你确定没有索引吗?或者索引在那里,但MySQL选择不使用它?一个大表将有15000000条记录。一个非常大的表有1500000000条记录。平均大小的表有150000个。供将来参考。请注意“或”可以使MySql不使用索引。我问了3个或更多的问题。每台机器都有一个索引,运行时间为15毫秒,总共需要25秒到超时。所以我做了3个查询,把它们联合在一起,它也在500行上花费了15Ms。考虑你正在存储的数据类型。性能可能会根据正在比较的数据类型而变化。正如您所说,PRODUCT_ID是一个VARCHAR数据类型,请尝试将其更改为INT并为列编制索引。我已经使用该SQL添加了索引,但它似乎尚未“应用”到数据,解释查询显示该字段没有索引。请使用SHOW CREATE TABLE检查索引,或者您已经这样做了吗?使用从您的表中显示索引
来检查索引是否已添加。今天,我遇到了@Michael所描述的确切问题,解决方案是“永远不要将整数与mysql中的字符串进行比较”。谢谢。@Wrikken我添加了我的索引,并使用了您的命令从您的表中显示索引。它出现了,但我认为在查询表时没有使用它。使用索引时我必须更改select查询吗?在MySQL中,如果您使用ALTER TABLE tbl ADD index(col)
而不是ALTER TABLE tbl ADD index col(col)
,那么多次使用ALTER TABLE tbl ADD index(col)
将继续添加名为col_2
,col_3
,。。。每一次。而第二次使用ALTER TABLE tbl ADD INDEX col(col)
时,将出现错误1061(42000):重复的键名“col”
。当我看到使用show INDEX时,哈希转换为btree。如果我不指定任何值,哈希和btree的默认值是多少?@RNKushwaha,因为InnoDB和MyIsam不支持哈希,AFAIK,只有内存和NDB存储引擎支持itNice,显式命名索引允许轻松检索