【问题标题】:Simple MySQL Table Running Slow Queries运行慢查询的简单 MySQL 表
【发布时间】:2023-04-09 14:17:01
【问题描述】:

我有一个非常简单的两列表格,但有 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 在返回大约 10 行之前会占用 CPU 并需要 2-5 秒。数据非常均匀地分布在表中,并且我正在访问索引字段(我还分析/优化了表,我从未更改表的内容),那么查询需要这么长时间的原因是什么?

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

【问题讨论】:

  • 均匀分布是什么意思?结果正确吗?您是否对 I/O 进行了概要分析?是否存在硬件延迟?
  • 均匀分布是指我没有将 ID 聚集在一起,因此 mysql BTREE 索引应该没有任何问题。

标签: sql mysql performance myisam


【解决方案1】:

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

按如下方式重新创建您的辅助密钥:

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

注意列顺序,这很重要。

【讨论】:

  • 这真的很奇怪。我正在使用navicat创建表,奇怪的是它以我想要的顺序显示列,但显然这个表创建查询以不同的顺序显示它们..它实际上是主键的顺序错误,因为我有在 content_id 之前的类别 ID,它们应该按该顺序键入。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    尝试改变:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多