优化MySQL连接查询以使用临时和索引删除?

优化MySQL连接查询以使用临时和索引删除?,mysql,optimization,join,indexing,Mysql,Optimization,Join,Indexing,我有一个按名称排序的查询,名称上的索引被忽略 如何优化查询以使用索引,并避免使用解释中的临时索引 我没有启用使用索引的日志查询,我看到这个查询数千次了 问题是: SELECT l.parent_id, j.id, j.location_id, j.currency, j.frequency, ROUND((j.salary_min + j.salary_max)/2) as salary FROM jobs AS j JOIN location AS l ON j.location_i

我有一个按名称排序的查询,名称上的索引被忽略

如何优化查询以使用索引,并避免使用解释中的临时索引

我没有启用使用索引的日志查询,我看到这个查询数千次了

问题是:

SELECT l.parent_id, j.id, j.location_id, j.currency, j.frequency, ROUND((j.salary_min + j.salary_max)/2) as salary 
FROM jobs AS j
JOIN location AS l
    ON j.location_id = l.id
WHERE j.salary_min !=0 
    AND j.status != 'Rejected'      
    AND l.published =1
    AND date_sub(now(), interval 1 month) <= j.effected_date
ORDER BY l.name
以及表格结构:

CREATE TABLE IF NOT EXISTS `jobs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `location_id` varchar(255) NOT NULL,
  `status` varchar(255) DEFAULT NULL,
  `currency` varchar(255) DEFAULT NULL,
  `salary_min` int(11) DEFAULT NULL,
  `salary_max` int(11) DEFAULT NULL,
  `effected_date` datetime DEFAULT NULL,
  `frequency` varchar(255) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  KEY `effected_date` (`effected_date`),
  KEY `location_id` (`location_id`),
  KEY `status` (`status`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10130 ;

CREATE TABLE IF NOT EXISTS `location` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(128) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=304 ;
将已发布的+id复合索引添加到位置表 将l.published=1条件移动到ON子句
这就是在你的情况下你能做的。但很可能,您永远不会放弃使用临时表,因为您不是按主表排序,而是按联接表排序。

这是因为您首先列出了作业。更改表的顺序,如下所示:

SELECT l.parent_id, j.id, j.location_id, j.currency, j.frequency, ROUND((j.salary_min + j.salary_max)/2) as salary 
FROM location AS l
JOIN jobs AS j  ON j.location_id = l.id
WHERE j.salary_min !=0 
AND j.status != 'Rejected'      
AND l.published =1
AND date_sub(now(), interval 1 month) <= j.effected_date
ORDER BY l.name

尝试一下并发布它的运行情况。

很多次,我都做过这样的查询,即在查询中有适当的主表作为第一个,索引良好,仅添加直接联接就可以修复查询。因此,根据您现有的标准,您应该熟悉日期索引,并将其用作主要标准。。。比如

SELECT STRAIGHT_JOIN
      L.Parent_ID, 
      J.id, 
      J.location_id, 
      J.currency, 
      J.frequency, 
      ROUND(( J.salary_min + J.salary_max) / 2 ) as Salary 
   FROM
      jobs J
         join Location L
            on J.Location_ID = L.ID
            AND L.Published = 1
   WHERE
          J.Effected_Date >= date_sub(now(), interval 1 month)
      AND J.salary_min != 0
      AND J.status != 'Rejected'
   ORDER BY 
      L.name

你能解释一下把l.published=1移到ON子句的意思吗?@David Rogers:ON j.location_id=l.id和l.published=1Hmm。。。我尝试了更改表位置添加索引id_pub id,published和更改表位置添加索引pub_id published,id。EXPLAIN仍然选择主j.id索引,不使用新索引。是的,我已经尝试过了。它仍然提供相同的解释输出。谢谢你=哈,我从来没有听说过“直联”,我得研究一下查询效果很好,但EXPLAIN仍然显示使用where;使用临时设备;使用文件排序
SELECT STRAIGHT_JOIN
      L.Parent_ID, 
      J.id, 
      J.location_id, 
      J.currency, 
      J.frequency, 
      ROUND(( J.salary_min + J.salary_max) / 2 ) as Salary 
   FROM
      jobs J
         join Location L
            on J.Location_ID = L.ID
            AND L.Published = 1
   WHERE
          J.Effected_Date >= date_sub(now(), interval 1 month)
      AND J.salary_min != 0
      AND J.status != 'Rejected'
   ORDER BY 
      L.name