首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用where;使用临时;使用文件

使用where;使用临时;使用文件
EN

Stack Overflow用户
提问于 2014-12-25 08:57:27
回答 1查看 5.4K关注 0票数 6

我有两张简单的桌子:

代码语言:javascript
运行
复制
CREATE TABLE cat_urls (
  Id int(11) NOT NULL AUTO_INCREMENT,
  SIL_Id int(11) NOT NULL,
  SiteId int(11) NOT NULL,
  AsCatId int(11) DEFAULT NULL,
  Href varchar(2048) NOT NULL,
  ReferrerHref varchar(2048) NOT NULL DEFAULT '',
  AddedOn datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  GroupId int(11) DEFAULT NULL,
  PRIMARY KEY (Id),
  INDEX SIL (SIL_Id, AsCatId)
)

CREATE TABLE products (
  Id int(11) NOT NULL AUTO_INCREMENT,
  CatUrlId int(11) NOT NULL,
  Href varchar(2048) NOT NULL,
  SiteIdentity varchar(2048) NOT NULL,
  Price decimal(12, 2) NOT NULL,
  IsAvailable bit(1) NOT NULL,
  ClientCode varchar(256) NOT NULL,
  PRIMARY KEY (Id),
  INDEX CatUrl (CatUrlId)
)

我有一个很简单的问题:

代码语言:javascript
运行
复制
SELECT cu.Href, COUNT(p.CatUrlId) FROM cat_urls cu
       JOIN products p ON p.CatUrlId=cu.Id
       WHERE sil_id=4601038
GROUP by cu.Id

解释说:

代码语言:javascript
运行
复制
id  select_type table   type    possible_keys   key     key_len ref                     rows    Extra
1   SIMPLE      cu      ref     PRIMARY,SIL     SIL     4       const                   303     Using where; Using temporary; Using filesort
1   SIMPLE      p       ref     CatUrl          CatUrl  4       blue_collar_logs.cu.Id  6       Using index

请告诉我有什么方法可以修复“在哪里使用临时文件”并提高这个查询的性能吗?

EN

回答 1

Stack Overflow用户

发布于 2015-01-13 12:21:20

看起来,出于某种原因,MySQL选择在第一个表上使用索引SIL,并将其用于查找(WHERE sil_id = 4601038)和分组(GROUP BY cu.Id)。

您可以告诉它使用表的PK

代码语言:javascript
运行
复制
SELECT cu.Href, COUNT(p.CatUrlId) FROM cat_urls cu
    USE INDEX FOR JOIN (PRIMARY)
JOIN products p ON p.CatUrlId=cu.Id
WHERE sil_id=4601038
GROUP by cu.Id

它将产生这样的执行计划:

代码语言:javascript
运行
复制
id | select_type | table | type  | possible_keys | key     | key_len | ref              | rows | Extra
---+-------------+-------+-------+---------------+---------+---------+------------------+------+-------------
1  | SIMPLE      | cu    | index | PRIMARY       | PRIMARY | 4       | NULL             | 1    | Using where
1  | SIMPLE      | p     | ref   | CatUrl        | CatUrl  | 4       | cbs-test-1.cu.Id | 1    | Using index

忽略列rows;中报告的值,这些值是不正确的,因为我的表是空的。

注意,Extra列现在只包含Using where,但也注意到join type列从ref (非常好)更改为index (完整索引扫描,不太好)。

更好的解决方案是在列SIL_Id上添加索引。我知道,SIL_Id是索引SIL(SIL_Id, AsCatId)的前缀,理论上,列SIL_Id上的另一个索引是完全无用的。但它似乎解决了这个案子的问题。

代码语言:javascript
运行
复制
ALTER TABLE cat_urls
  ADD INDEX (SIL_Id)
;

现在在查询中使用它:

代码语言:javascript
运行
复制
SELECT cu.Href, COUNT(p.CatUrlId) FROM cat_urls cu
    USE INDEX FOR JOIN (SIL_Id)
JOIN products p ON p.CatUrlId=cu.Id
WHERE sil_id=4601038
GROUP by cu.Id

查询执行计划现在看起来好多了:

代码语言:javascript
运行
复制
id | select_type | table | type | possible_keys | key    | key_len | ref              | rows | Extra
---+-------------+-------+------+---------------+--------+---------+------------------+------+-------------
1  | SIMPLE      | cu    | ref  | SIL_Id        | SIL_Id | 4       | const            | 1    | Using where
1  | SIMPLE      | p     | ref  | CatUrl        | CatUrl | 4       | cbs-test-1.cu.Id | 1    | Using index

缺点是我们有一个额外的索引(理论上)是无用的。它占用存储空间,每次添加、删除或修改其SIL_Id字段时都会消耗处理器周期。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27645719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档