运行缓慢查询的简单 MySQL 表

发布于 2024-07-22 05:45:25 字数 583 浏览 7 评论 0原文

我有一个非常简单的表,有两列,但有 450 万行。

CREATE TABLE `content_link` (
  `category_id` mediumint(8) unsigned NOT NULL,
  `content_id` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`content_id`,`category_id`),
  KEY `content_id` (`content_id`,`category_id`)
) ENGINE=MyISAM;

当我运行一个简单的查询时,例如:

SELECT
    *   
FROM
    content_link
WHERE
    category_id = '11';

mysql 使 CPU 达到峰值,并需要 2-5 秒才能返回大约 10 行。 数据在表中分布非常均匀,并且我正在访问索引字段(我还分析/优化了表,并且从未更改表的内容),那么查询需要这么长时间的原因是什么?

编辑:navicat 似乎在对我撒谎,我的主键实际上没有按正确的顺序键入,因为它向我显示了表格。

I have a very simple table with two columns, but has 4.5M rows.

CREATE TABLE `content_link` (
  `category_id` mediumint(8) unsigned NOT NULL,
  `content_id` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`content_id`,`category_id`),
  KEY `content_id` (`content_id`,`category_id`)
) ENGINE=MyISAM;

When I run a simple query like:

SELECT
    *   
FROM
    content_link
WHERE
    category_id = '11';

mysql spikes the CPU and takes 2-5 seconds before returning about 10 rows. The data is spread very evenly across the table and I'm accessing indexed fields (I've also analyzed/optimized the table and I never change the content of the table), so what reason is there for the query to take so long?

Edit: It seems navicat was lying to me and my primary key was not actually keyed in the right order as it was displaying the table to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

余生共白头 2024-07-29 05:45:25

category_id 不是任何索引中的第一列。

按如下方式重新创建辅助键:

UNIQUE KEY `ix_category_id` (`category_id`, `content_id`)

注意列顺序,这很重要。

category_id is not the first column in any index.

Recreate your secondary key as follows:

UNIQUE KEY `ix_category_id` (`category_id`, `content_id`)

Note the column order, it matters.

GRAY°灰色天空 2024-07-29 05:45:25

UNIQUE KEY 排序是一个很好的解决方案,您也应该向表添加分区策略。

通过将表分区为片段,MySQL 将使用正确的数据集查询特定分区。 我已经申请了并且取得了很好的结果。

CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
ENGINE=INNODB
PARTITION BY HASH( MONTH(tr_date) )
PARTITIONS 6;

您需要 MySQL 5.1。

尝试 http://dev.mysql.com/doc/refman/5.1 /en/partitioning.html

The UNIQUE KEY ordering is a good solution and you should add a partition strategy to your table too.

By partitioning the table in fragments, MySQL will query the specific partition with the right data set. I've applied and I had excellent results.

CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
ENGINE=INNODB
PARTITION BY HASH( MONTH(tr_date) )
PARTITIONS 6;

You need MySQL 5.1.

Try http://dev.mysql.com/doc/refman/5.1/en/partitioning.html

放我走吧 2024-07-29 05:45:25

您没有使用索引。 当您有像 (content_id,category_id) 这样的复合索引时,您可以使用 content_id 来使用索引,也可以使用 content_id类别_id。 您不能使用 category_id 并利用索引。

尝试改变

KEY `content_id` (`content_id`, `category_id`)

KEY `category_id` (`category_id`, `content_id`)

You are not using the index. When you have a composite index like (content_id, category_id) you can use the index by using content_id or you can use content_id and category_id. You can't use category_id and utilize the index.

Try changing:

KEY `content_id` (`content_id`, `category_id`)

to

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