如何为 MySQL 表添加索引?

发布于 2024-09-05 01:13:18 字数 916 浏览 2 评论 0原文

我有一个非常大的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

×纯※雪 2024-09-12 01:13:18
ALTER TABLE `table` ADD INDEX `product_id_index` (`product_id`)

切勿在 MySQL 中将整数字符串进行比较。如果 idint,请删除引号。

ALTER TABLE `table` ADD INDEX `product_id_index` (`product_id`)

Never compare integer to strings in MySQL. If id is int, remove the quotes.

╰沐子 2024-09-12 01:13:18
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);
゛时过境迁 2024-09-12 01:13:18

您可以使用此语法添加索引并控制索引的类型(HASH 或 BTREE)。

create index your_index_name on your_table_name(your_column_name) using HASH;

或者

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

You can use this syntax to add an index and control the kind of index (HASH or 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;

You can learn about differences between BTREE and HASH indexes here:
http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html

窝囊感情。 2024-09-12 01:13:18

可以添加两种类型的索引:当定义主键时,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`)

以上语句将创建一个名为 student_index 的普通索引。

创建唯一索引

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_fulltext_index 的全文索引,为此您需要 MyISAM Mysql Engine。

如何删除索引?

DROP INDEX `student_index` ON `tbl_student`

如何检查可用索引?

SHOW INDEX FROM `tbl_student`

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 want student_id as primary key:

ALTER TABLE `tbl_student` ADD PRIMARY KEY (`student_id`)

Above statement adds a primary key, which means that indexed values must be unique and cannot be NULL.

Specify index name

ALTER TABLE `tbl_student` ADD INDEX student_index (`student_id`)

Above statement will create an ordinary index with student_index name.

Create unique index

ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)

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

ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)

Above statement will create the Fulltext index name with student_fulltext_index, for which you need MyISAM Mysql Engine.

How to remove indexes ?

DROP INDEX `student_index` ON `tbl_student`

How to check available indexes?

SHOW INDEX FROM `tbl_student`
携余温的黄昏 2024-09-12 01:13:18

值得注意的是,多个字段索引可以极大地提高查询性能。因此,在上面的示例中,我们假设 ProductID 是唯一要查找的字段,但如果查询为 ProductID = 1 AND Category = 7,则多列索引会有所帮助。这是通过以下方式实现的:

ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)

此外,索引应该与查询字段的顺序匹配。在我的扩展示例中,索引应该是 (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:

ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)

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.

等你爱我 2024-09-12 01:13:18

你说你有一个索引,解释说不然。然而,如果你真的这样做,这就是如何继续:

如果你在列上有一个索引,而 MySQL 决定不使用它,可能是因为:

  1. 查询中还有另一个索引 MySQL 认为更适合使用,并且它只能使用一个。如果正常的检索方法是通过多于一列的值进行检索,那么解决方案通常是跨多列的索引。
  2. MySQL 认为有很多匹配行,并认为表扫描可能更快。如果情况并非如此,有时分析表会有所帮助。
  3. 在更复杂的查询中,它决定不使用它,这是基于查询计划中极其智能的深思熟虑的巫毒,由于某种原因,它不符合您当前的要求。

对于(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:

  1. There's another index in the query MySQL deems more appropriate to use, and it can use only one. The solution is usually an index spanning multiple columns if their normal method of retrieval is by value of more then one column.
  2. MySQL decides there are to many matching rows, and thinks a tablescan is probably faster. If that isn't the case, sometimes an ANALYZE TABLE helps.
  3. In more complex queries, it decides not to use it based on extremely intelligent thought-out voodoo in the query-plan that for some reason just not fits your current requirements.

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.

冷弦 2024-09-12 01:13:18

更好的选择是在 CREATE TABLE 查询期间直接添加约束(假设您有有关表的信息)

CREATE TABLE products(
    productId INT AUTO_INCREMENT PRIMARY KEY,
    productName varchar(100) not null,
    categoryId INT NOT NULL,
    CONSTRAINT fk_category
    FOREIGN KEY (categoryId) 
    REFERENCES categories(categoryId)
        ON UPDATE CASCADE
        ON DELETE CASCADE
) ENGINE=INNODB;

A better option is to add the constraints directly during CREATE TABLE query (assuming you have the information about the tables)

CREATE TABLE products(
    productId INT AUTO_INCREMENT PRIMARY KEY,
    productName varchar(100) not null,
    categoryId INT NOT NULL,
    CONSTRAINT fk_category
    FOREIGN KEY (categoryId) 
    REFERENCES categories(categoryId)
        ON UPDATE CASCADE
        ON DELETE CASCADE
) ENGINE=INNODB;
失与倦" 2024-09-12 01:13:18

使用phpmyadmin,MySQL管理的好工具,包括索引

use phpmyadmin, great tool for MySQL managing, include indexing

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文