如何为 MySQL 表添加索引?
我有一个非常大的 MySQL 表,包含大约 150,000 行数据。目前,当我尝试运行
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,这可能会有所帮助。这可能是问题的根源吗?
I've got a very large MySQL table with about 150,000 rows of data. Currently, when I try and run
SELECT * FROM table WHERE id = '1';
the code runs fine as the ID field is the primary index.
However, for a recent development in the project, I have to search the database by another field. For example:
SELECT * FROM table WHERE product_id = '1';
This field was not previously indexed; however, I've added one, so mysql now indexes the field, but when I try to run the above query, it runs very slowly. An EXPLAIN query reveals that there is no index for the product_id field when I've already added one, and as a result the query takes any where from 20 minutes to 30 minutes to return a single row.
My full EXPLAIN results are:
| id | select_type | table | type | possible_keys| key | key_len | ref | rows | Extra |
+----+-------------+-------+------+--------------+------+---------+------+-------+------------------+
| 1 | SIMPLE | table | ALL | NULL | NULL | NULL | NULL |157211 | Using where |
+----+-------------+-------+------+--------------+------+---------+------+-------+------------------+
It might be helpful to note that I've just taken a look, and ID field is stored as INT whereas the PRODUCT_ID field is stored as VARCHAR. Could this be the source of the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
切勿在 MySQL 中将
整数
与字符串
进行比较。如果id
为int
,请删除引号。Never compare
integer
tostrings
in MySQL. Ifid
isint
, remove the quotes.您可以使用此语法添加索引并控制索引的类型(HASH 或 BTREE)。
或者
您可以在此处了解 BTREE 和 HASH 索引之间的差异:
http://dev.mysql.com/doc/refman /5.5/en/index-btree-hash.html
You can use this syntax to add an index and control the kind of index (HASH or BTREE).
or
You can learn about differences between BTREE and HASH indexes here:
http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html
可以添加两种类型的索引:当定义主键时,MySQL默认将其作为索引。
说明
主键作为索引
假设您有一个
tbl_student
表,并且您希望student_id
作为主键:以上语句添加主键,这意味着索引值必须是唯一的并且不能为 NULL。
指定索引名称
以上语句将创建一个名为
student_index
的普通索引。创建唯一索引
这里,
student_unique_index
是分配给student_id的索引名称,并创建一个索引,其值必须是唯一的(这里可以接受null)。全文选项
上面的语句将创建名为
student_fulltext_index
的全文索引,为此您需要 MyISAM Mysql Engine。如何删除索引?
如何检查可用索引?
Indexes of two types can be added: when you define a primary key, MySQL will take it as index by default.
Explanation
Primary key as index
Consider you have a
tbl_student
table and you wantstudent_id
as primary key:Above statement adds a primary key, which means that indexed values must be unique and cannot be NULL.
Specify index name
Above statement will create an ordinary index with
student_index
name.Create unique index
Here,
student_unique_index
is the index name assigned to student_id and creates an index for which values must be unique (here null can be accepted).Fulltext option
Above statement will create the Fulltext index name with
student_fulltext_index
, for which you need MyISAM Mysql Engine.How to remove indexes ?
How to check available indexes?
值得注意的是,多个字段索引可以极大地提高查询性能。因此,在上面的示例中,我们假设 ProductID 是唯一要查找的字段,但如果查询为 ProductID = 1 AND Category = 7,则多列索引会有所帮助。这是通过以下方式实现的:
此外,索引应该与查询字段的顺序匹配。在我的扩展示例中,索引应该是 (ProductID,Category) 而不是相反。
It's worth noting that multiple field indexes can drastically improve your query performance. So in the above example we assume ProductID is the only field to lookup but were the query to say ProductID = 1 AND Category = 7 then a multiple column index helps. This is achieved with the following:
Additionally the index should match the order of the query fields. In my extended example the index should be (ProductID,Category) not the other way around.
你说你有一个索引,解释说不然。然而,如果你真的这样做,这就是如何继续:
如果你在列上有一个索引,而 MySQL 决定不使用它,可能是因为:
分析表
会有所帮助。对于(2)或(3)的情况,你可以通过 索引提示语法,但如果这样做,请务必运行一些测试来确定在提示时使用索引是否确实提高了性能。
You say you have an index, the explain says otherwise. However, if you really do, this is how to continue:
If you have an index on the column, and MySQL decides not to use it, it may by because:
ANALYZE TABLE
helps.In the case of (2) or (3), you could coax MySQL into using the index by index hint sytax, but if you do, be sure run some tests to determine whether it actually improves performance to use the index as you hint it.
更好的选择是在 CREATE TABLE 查询期间直接添加约束(假设您有有关表的信息)
A better option is to add the constraints directly during CREATE TABLE query (assuming you have the information about the tables)
使用phpmyadmin,MySQL管理的好工具,包括索引
use phpmyadmin, great tool for MySQL managing, include indexing