Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当MySQL优化器选择不在一个小的连接表上使用键时,如何避免全表扫描_Mysql_Query Optimization - Fatal编程技术网

当MySQL优化器选择不在一个小的连接表上使用键时,如何避免全表扫描

当MySQL优化器选择不在一个小的连接表上使用键时,如何避免全表扫描,mysql,query-optimization,Mysql,Query Optimization,我遇到了一个奇怪的问题,我不知道如何正确地搜索这个场景。我在下面提供了两个表格: CREATE TABLE revenue_centers ( revc_id int(11) NOT NULL AUTO_INCREMENT, revc_name varchar(50) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (revc_id) ) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8 C

我遇到了一个奇怪的问题,我不知道如何正确地搜索这个场景。我在下面提供了两个表格:

CREATE TABLE revenue_centers (
 revc_id int(11) NOT NULL AUTO_INCREMENT,
 revc_name varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (revc_id)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE cpt (
 cpt_id int(11) NOT NULL AUTO_INCREMENT,
 cpt_revc_id int(11) NOT NULL,
 PRIMARY KEY (cpt_id),
 KEY cpt_revc_id (cpt_revc_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
有更多的列,但上面的列是所有需要的。这些表跨多个客户的独立数据库复制。以下是我提出的问题之一:

select*from cpt left join revenue\u centers on cpt\u revc\u id=revc\u id order by cpt\u id

使用EXPLAIN,在收入中心中至少有4行的表上,我们得到以下结果:

 1  SIMPLE  cpt             index   PRIMARY         4                       89664
 1  SIMPLE  revenue_centers eq_ref  PRIMARY PRIMARY 4   _8.cpt.cpt_revc_id  1
 1  SIMPLE  cpt             ALL             22725   Using temporary; Using filesort
 1  SIMPLE  revenue_centers ALL  PRIMARY    1       Using where; Using join buffer (Block Nested Loop)
查询速度快,没有延迟。对于不使用收入中心的客户,我们提供以下服务:

 1  SIMPLE  cpt             index   PRIMARY         4                       89664
 1  SIMPLE  revenue_centers eq_ref  PRIMARY PRIMARY 4   _8.cpt.cpt_revc_id  1
 1  SIMPLE  cpt             ALL             22725   Using temporary; Using filesort
 1  SIMPLE  revenue_centers ALL  PRIMARY    1       Using where; Using join buffer (Block Nested Loop)
我理解,因为对收入中心的完全扫描可能比索引1便宜,mysql选择使用连接缓冲区。我不明白为什么它选择在cpt表上进行完全扫描

如果我在连接上使用FORCE INDEX提示,它将变成eq_ref类型的连接,cpt查询不再使用临时表或filesort。如果可能的话,我希望避免将其添加到我们的代码中。我尝试将max_seeks_for_key设置为低至1,以查看是否可以强制优化器在没有索引提示的情况下使用主键,但它拒绝更改


除了将强制索引添加到我们的代码库之外,还有什么方法可以改进此查询或至少防止使用临时表吗?

@bill karwin感谢您提供的格式帮助。
ORDER BY
优化需要多列索引。它在MySQL手册中。。因此,您需要创建索引
cpt(cpt\u revc\u id,cpt\u id)
,以避免“使用临时;使用文件排序”,您的意思是,在慢速情况下,
收入中心中没有行
。。。每个查询需要多长时间?@RaymondNijland-因为这是InnoDB,这实际上就是索引中包含的内容。