优化mysql查询(使用或创建索引)

优化mysql查询(使用或创建索引),mysql,select,indexing,Mysql,Select,Indexing,我有一个使PHP超时的SQL请求(mySQL 5.1.51)。 我想优化它,但我找不到缺少什么。 请求是: SELECT s_i.incident, s.hostname, a.application, s_ie.problem_status, s_i.open_time, s_i.close_time, s_ie.open_group, s_ie.primary_assignment,

我有一个使PHP超时的SQL请求(mySQL 5.1.51)。 我想优化它,但我找不到缺少什么。 请求是:

SELECT s_i.incident,
       s.hostname,
       a.application,
       s_ie.problem_status,
       s_i.open_time,
       s_i.close_time,
       s_ie.open_group,
       s_ie.primary_assignment,
       s_ie.closed_by_group,
       s_ie.contact_first_name,
       s_ie.contact_last_name,
       s_ie.description,
       s_ie.resolution,
       s_ie.famille_1,
       s_ie.famille_2,
       s_ie.famille_3,
       YEARWEEK(s_i.open_time)              AS 'semaine_ouverture',
       DATE_FORMAT(s_i.open_time,  '%Y-%m') AS 'mois_ouverture',
       YEARWEEK(s_i.close_time)             AS 'semaine_cloture',
       DATE_FORMAT(s_i.close_time, '%Y-%m') AS 'mois_cloture',
       p.nom,
       s.exploite_par,
       t.environnement,
       a.tdb
FROM t_link_serveur_eac t USE KEY(nna)
     INNER JOIN serveur          s    ON s.id            = t.id_serveur
     INNER JOIN plateau          p    ON p.id            = t.id_plateau
     INNER JOIN applications     a    ON a.nna           = t.nna
     INNER JOIN scope_i          s_i  USE KEY (id_serveur) ON s_i.id_serveur  = t.id_serveur
     INNER JOIN scope_i_extended s_ie USE KEY (id_scope_i) ON s_ie.id_scope_i = s_i.id
WHERE s_ie.problem_status     = 'Closed'
AND   s_ie.contact_first_name = 'AUTOMATE'
AND   s_ie.contact_last_name LIKE '%BEM%'
AND   p.id           = 4
AND   open_time >= CURDATE() - INTERVAL 52 WEEK AND open_time <= CURDATE()
AND   AND s_i.close_time < CURDATE() - INTERVAL DAYOFMONTH(CURDATE()) - 1 DAY
ORDER BY mois_cloture
s_ie有712000条线路,s_i有740.000条线路,所以我认为问题出在这个路口

下面是表s_ie的结构

CREATE TABLE IF NOT EXISTS `scope_i_extended` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_scope_i` int(11) NOT NULL,
  `problem_status` varchar(16) NOT NULL,
  `open_group` varchar(32) NOT NULL,
  `primary_assignment` varchar(32) NOT NULL,
  `closed_by_group` varchar(32) NOT NULL,
  `contact_first_name` varchar(32) NOT NULL,
  `contact_last_name` varchar(32) NOT NULL,
  `description` text NOT NULL,
  `resolution` text NOT NULL,
  `famille_1` text NOT NULL,
  `famille_2` text NOT NULL,
  `famille_3` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_scope_i` (`id_scope_i`),
  UNIQUE KEY `problem_status` (`id_scope_i`, `problem_status`, `contact_first_name`, `contact_last_name`),
  KEY `contact_last_name` (`contact_last_name`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
以及s_i的结构

CREATE TABLE IF NOT EXISTS `scope_i` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `incident` varchar(20) NOT NULL,
  `statut` varchar(20) NOT NULL,
  `id_serveur` int(11) NOT NULL,
  `open_time` datetime NOT NULL,
  `close_time` datetime DEFAULT NULL,
  `affectation` varchar(50) NOT NULL,
  `titre` varchar(200) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `incident` (`incident`),
  KEY `serveur` (`id_serveur`),
  KEY `serveur_open_time` (`id_serveur`,`open_time`),
  KEY `id_serveur` (`id_serveur`,`close_time`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=738862 ;
你能帮我吗

问候,


Olivier

很抱歉,我建议使用:
“年周(开放时间)='201146'

而不是
“年周(开放时间)在(…)”


IN总是会让事情变得非常缓慢。

很抱歉,我建议使用:
“年周(开放时间)='201146'

而不是
“年周(开放时间)在(…)”


在您的情况下,Mysql函数中包含日期列。 例如:
YEARWEEK(开放时间)
DATE(开放时间)
您应该避免这种情况,因为Mysql似乎为表的每一行执行函数

你能试着换一个吗

DATE\u格式(s\u i.close\u time,“%Y-%m-%d”)

s\u i.close\u时间

YEARWEEK(开放时间)在('201246'、'201245'…)

由此:(以下是一年内获得所有记录的“开放时间”的条件。我不确定这是否是您的情况)


open\u time>=CURDATE()-间隔1年和open\u time在您的情况下,Mysql函数中包含日期列。
例如:
YEARWEEK(开放时间)
DATE(开放时间)
您应该避免这种情况,因为Mysql似乎为表的每一行执行函数

你能试着换一个吗

DATE\u格式(s\u i.close\u time,“%Y-%m-%d”)

s\u i.close\u时间

YEARWEEK(开放时间)在('201246'、'201245'…)

由此:(以下是一年内获得所有记录的“开放时间”的条件。我不确定这是否是您的情况)


open\u time>=CURDATE()-间隔1年和open\u time发布查询执行计划。请只编辑问题并将其放在那里,不要尝试在注释中添加输出。事实上,注释无法格式化为使执行计划正确可读。我编辑了问题并添加了它。您正在按计算字段(mois_cloture)排序记录。尝试删除ORDERBY子句并注意查询执行时间。它可能会大大降低。此外,如果您的结果集与您在其中一条评论(30000多条记录)中所述的结果集一样大,则客户端接收和缓冲肯定也会造成延迟。同时发布查询执行计划请只编辑问题并将其放在那里,不要尝试在评论中添加输出,无法将注释格式化为使执行计划正确可读。我编辑了问题并添加了它。您正在按计算字段(mois_cloture)排序记录。尝试删除ORDERBY子句并注意查询执行时间。它可能会大大降低。此外,如果您的结果集与您在其中一条评论(30000多条记录)中所述的结果集一样大,那么客户端接收和缓冲肯定也会产生延迟。事实上,这是我看到的一点,我将要求开发人员优化这一部分(waybe with BETWEEN)@Olivier Gérault您可能想在开发人员处丢弃此链接:谢谢,我阅读了它并应用了建议,但仍然因为超时而在PHP中执行失败。事实上,这是我看到的一点,我也会要求开发人员优化此部分(waybe with BETWEEN)@Olivier Gérault你可能想把这个链接扔给开发人员:谢谢,我读了它并应用了建议,但是仍然因为超时而在PHP中执行失败。谢谢你的建议。我应用了它们,这使我节省了执行时间(1.5s vs 1.08s)。然而,它仍然失败。我忘了说结果是31000行的数组谢谢你的建议。我应用了它们,这使我节省了执行时间(1.5s vs 1.08s)。然而,它仍然失败。我忘了说结果是一个31000行的数组
CREATE TABLE IF NOT EXISTS `scope_i` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `incident` varchar(20) NOT NULL,
  `statut` varchar(20) NOT NULL,
  `id_serveur` int(11) NOT NULL,
  `open_time` datetime NOT NULL,
  `close_time` datetime DEFAULT NULL,
  `affectation` varchar(50) NOT NULL,
  `titre` varchar(200) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `incident` (`incident`),
  KEY `serveur` (`id_serveur`),
  KEY `serveur_open_time` (`id_serveur`,`open_time`),
  KEY `id_serveur` (`id_serveur`,`close_time`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=738862 ;