Mysql 加入/分类缓慢运行

Mysql 加入/分类缓慢运行,mysql,sql,join,sql-order-by,Mysql,Sql,Join,Sql Order By,我花了几个小时制作了一个SQL查询,该查询执行一个连接,并将两列排序在一起,这种方式我以前从未处理过。以下是查询: SELECT `m`.`id`, `m`.`primary_category_id`, `m`.`primary_category_priority`, `m`.`description` FROM (`merchant` AS m) LEFT JOIN `merchant_category` ON `merchant_category`.`merchant_id` = `

我花了几个小时制作了一个SQL查询,该查询执行一个
连接
,并将两列排序在一起,这种方式我以前从未处理过。以下是查询:

SELECT `m`.`id`, `m`.`primary_category_id`, `m`.`primary_category_priority`, `m`.`description`
FROM (`merchant` AS m)
LEFT JOIN `merchant_category`
    ON `merchant_category`.`merchant_id` = `m`.`id`
WHERE
    `merchant_category`.`category_id` = '2'
    OR `m`.`primary_category_id` = '2'
GROUP BY `m`.`id`
ORDER BY
    LEAST(merchant_category.priority = 0, `primary_category_priority` = 0) ASC,
    LEAST(merchant_category.priority, `primary_category_priority` ) ASC
LIMIT 10
它必须将两列排序在一起,一列来自merchant_category表,另一列来自merchant表,以便将它们排序在一起。
商户
的每一行都有一个表中直接提及的“主要”类别,以及存储在
商户_类别
表中的零个或多个“次要”类别。现在它工作正常,但速度非常慢:在我的生产数据库上通常超过一分钟。我想是
连接
加上复杂的排序造成了这个问题,但是我能做什么呢

编辑以下是两个表的模式:

CREATE TABLE IF NOT EXISTS `merchant` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) CHARACTER SET utf8 NOT NULL,
  `primary_category_id` int(11) NOT NULL,
  `primary_category_priority` int(10) unsigned NOT NULL DEFAULT '0',
  `description` mediumtext CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE IF NOT EXISTS `merchant_category` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `merchant_id` int(10) NOT NULL,
  `category_id` int(10) NOT NULL,
  `priority` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
)

您强制它对每一行运行
至少
(两次!)以便对其进行排序。它无法对此使用索引。

您正在强制它对每一行至少运行
(两次!),以便对其进行排序。它无法对此使用索引。

尝试在第二个表上添加外键约束

CREATE TABLE IF NOT EXISTS `merchant_category` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `merchant_id` int(10) NOT NULL,
  `category_id` int(10) NOT NULL,
  `priority` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  CONSTRAINT mc_fk FOREIGN KEY (`merchant_id`) REFERENCES `merchant`(`id`)
)

尝试在第二个表上添加外键约束

CREATE TABLE IF NOT EXISTS `merchant_category` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `merchant_id` int(10) NOT NULL,
  `category_id` int(10) NOT NULL,
  `priority` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  CONSTRAINT mc_fk FOREIGN KEY (`merchant_id`) REFERENCES `merchant`(`id`)
)


您能否发布表的架构,特别是
merchant
merchant\u category
?也许你错过了一些索引。你的索引设置正确吗?两个表中有多少行?@Erik
merchant
我相信有20000多行,
merchant\u category
的行数是原来的几倍。@JohnWoo我添加了表架构。你能具体发布表架构吗
merchant
merchant\u category
?也许你错过了一些索引。你的索引设置正确吗?两个表中有多少行?@Erik
merchant
我相信有20000多行,而
merchant\u category
的行数是原来的几倍。@JohnWoo我添加了表架构。您推荐什么替代方案?我必须使用
LEAST
将这两个数字进行整合,以便对它们进行排序。另外两个小注释。“
merchant\u category
category\u id
=”2“不应该是
加入的一部分吗?您应该有一个复合索引,其中包括您选择的对象和主键,因此(primary_category_id,id)。
EXPLAIN
会在该表上显示一个表扫描…我不知道它是否会更快,但感觉您应该使用
CASE
语句作为
SELECT
的一部分来确定优先级,然后按指定的列进行排序。
在这种情况下,
语句就是所选的特定类别,它可以是任何类型。您推荐什么作为替代方法?我必须使用
最小值
将这两个数字进行集成,以便将它们排序在一起。另外两个小注释。“
merchant\u category
category\u id
=”2“不应该是
加入的一部分吗?您应该有一个复合索引,其中包括您选择的对象和主键,因此(primary_category_id,id)。
EXPLAIN
会在该表上显示一个表扫描…我不知道它是否会更快,但感觉您应该使用
CASE
语句作为
SELECT
的一部分来确定优先级,然后按指定的列进行排序。
其中
语句就是在本例中选择的特定类别,它可以是任何内容。@Jonah您想排序什么?按两个不同表中的优先级编号排序。在主类别的
merchant
表中,以及在次要类别的
merchant\u category
表中。好的,我添加了外键约束,我是否希望我的查询现在运行得更快?可能与预期的一样。你试着再次运行查询了吗?哇,这让查询速度加快了很多,现在基本上是即时的。谢谢@约拿:你想排序什么?按两个不同表中的优先级编号排序。在主类别的
merchant
表中,以及在次要类别的
merchant\u category
表中。好的,我添加了外键约束,我是否希望我的查询现在运行得更快?可能与预期的一样。你试着再次运行查询了吗?哇,这让查询速度加快了很多,现在基本上是即时的。谢谢