Mysql 当列上存在键时,为什么索引不用于Group by和/或Join
我有一个疑问:Mysql 当列上存在键时,为什么索引不用于Group by和/或Join,mysql,sql,join,indexing,sql-execution-plan,Mysql,Sql,Join,Indexing,Sql Execution Plan,我有一个疑问: SELECT p.prodno AS id, proddesc AS label FROM product p JOIN sales s ON s.custno = 00800 AND s.deptno = 0 AND s.prodno = p.prodno GROUP BY p.prodno ORDER BY p.prodno ASC 解释一下: +---+
SELECT p.prodno AS id,
proddesc AS label
FROM product p
JOIN sales s
ON s.custno = 00800
AND s.deptno = 0
AND s.prodno = p.prodno
GROUP BY p.prodno
ORDER BY p.prodno ASC
解释一下:
+---+-----------+------+--------+------------------------------------------------------------------------------+------------+------+----------------------------------------+------+---------+------------------------------------+
| 1 | 'SIMPLE' | 'p' | 'ALL' | 'PRIMARY' | '' | '' | '' | 481 | 100.00 | 'Using temporary; Using filesort' |
| 1 | 'SIMPLE' | 's' | 'ref' | 'PRIMARY,in_sales_custnodeptnoprodno,in_sales_deptnocustno,in_sales_custno' | 'PRIMARY' | '6' | 'const,const,bkp_teststats2.p.PRODNO' | 93 | 100.00 | 'Using index' |
+---+-----------+------+--------+------------------------------------------------------------------------------+------------+------+----------------------------------------+------+---------+------------------------------------+
正如您所看到的,在PRODNO的第一行中没有使用索引,但表架构在其上有索引
CREATE TABLE IF NOT EXISTS `product` (
`PRODNO` decimal(4,0) unsigned zerofill NOT NULL DEFAULT '0000',
`PRODDESC` char(21) NOT NULL DEFAULT '',
`UPCCODE12` decimal(12,0) unsigned zerofill NOT NULL DEFAULT '000000000000',
PRIMARY KEY (`PRODNO`)
)
销售人员有以下关键:
PRIMARY KEY (`CUSTNO`,`DEPTNO`,`PRODNO`,`ARDATE8N`),
KEY `in_sales_custnodeptnoprodno` (`CUSTNO`,`DEPTNO`,`PRODNO`),
KEY `in_sales_deptnocustno` (`DEPTNO`,`CUSTNO`),
KEY `in_sales_custno` (`CUSTNO`),
我想放弃使用临时的;使用filesort
,因为上面的查询在50G数据表上需要14秒
更新:
问题:我想获取一个唯一的产品列表,该列表包含给定客户号和部门号的销售数据。数据库必须检查
产品表中的每一行,以满足您的查询。如果它使用索引,它必须返回每一行的主表以获取proddesc
。返回主表(“书签查找”)是相当昂贵的。因此,查询优化器选择对主表进行扫描和排序,这对我来说似乎是一个不错的选择
如果从结果中省略了proddesc
,则查询只需要prodno
。在这种情况下,查询优化器可能会使用索引
您还可以将产品
上的索引从(prodno)
扩展到(prodno,proddesc)
。通过这种方式扩展,索引可以满足查询,而无需查找表。数据库必须检查产品
表中的每一行以满足您的查询。如果它使用索引,它必须返回每一行的主表以获取proddesc
。返回主表(“书签查找”)是相当昂贵的。因此,查询优化器选择对主表进行扫描和排序,这对我来说似乎是一个不错的选择
如果从结果中省略了proddesc
,则查询只需要prodno
。在这种情况下,查询优化器可能会使用索引
您还可以将产品
上的索引从(prodno)
扩展到(prodno,proddesc)
。通过这种方式扩展,索引可以满足查询,而无需查找表。事实上,plus还将补充说,mysql可能是“成熟”关系数据库之一,允许选择未在GROUP BY
或聚合函数中使用的字段,因此,优化此类查询更为困难。我可以通过两种选择来实现这一点吗?可能首先只选择prodno
,然后再次加入虚拟表以获取proddesc
。这会有帮助吗?@zerkms Group by用于不同的替代方案,因为在本场景中比distinct@Pentium10:你还没有描述你真正想要做什么。@Pentium10:好吧,如果它更快,那你为什么在这里?如果速度不够快,为什么不先全面解释一下您现在拥有什么以及您想要实现什么?事实上,plus还将补充说,mysql可能是一个“成熟”的关系数据库,它允许选择未在分组方式
或聚合函数中使用的字段,因此,优化这样的查询就越困难。我可以选择两种方法来实现这一点吗?可能首先只选择prodno
,然后再次加入虚拟表以获取proddesc
。这会有帮助吗?@zerkms Group by用于不同的替代方案,因为在本场景中比distinct@Pentium10:你还没有描述你真正想要做什么。@Pentium10:好吧,如果它更快,那你为什么在这里?如果速度不够快,为什么不从全面解释你现在拥有的和你想要实现的目标开始呢?