【问题标题】:Improve query speed suggestions提高查询速度建议
【发布时间】:2019-09-27 11:15:13
【问题描述】:

为了自学,我正在为一家电力公司开发一个发票系统。我有多个时间序列表,间隔不同。一张表代表消费,另外两张代表价格。仍应包含第三个价格表。现在我正在运行计算查询,但查询速度很慢。我想提高查询速度,特别是因为这只是开始计算,查询只会变得更加复杂。另请注意,这是我创建的第一个数据库和我做过的练习。最好是简化的解释。感谢您提供的任何帮助。

我已在每个表中编入索引:DATE, PERIOD_FROM, PERIOD_UNTIL。这将过程从 60 秒加快到 5 秒。

表格的结构如下:

CREATE TABLE `apxprice` (
 `APX_id` int(11) NOT NULL AUTO_INCREMENT,
 `DATE` date DEFAULT NULL,
 `PERIOD_FROM` time DEFAULT NULL,
 `PERIOD_UNTIL` time DEFAULT NULL,
 `PRICE` decimal(10,2) DEFAULT NULL,
 PRIMARY KEY (`APX_id`)
) ENGINE=MyISAM AUTO_INCREMENT=28728 DEFAULT CHARSET=latin1

CREATE TABLE `imbalanceprice` (
 `imbalanceprice_id` int(11) NOT NULL AUTO_INCREMENT,
 `DATE` date DEFAULT NULL,
 `PTU` tinyint(3) DEFAULT NULL,
 `PERIOD_FROM` time DEFAULT NULL,
 `PERIOD_UNTIL` time DEFAULT NULL,
 `UPWARD_INCIDENT_RESERVE` tinyint(1) DEFAULT NULL,
 `DOWNWARD_INCIDENT_RESERVE` tinyint(1) DEFAULT NULL,
 `UPWARD_DISPATCH` decimal(10,2) DEFAULT NULL,
 `DOWNWARD_DISPATCH` decimal(10,2) DEFAULT NULL,
 `INCENTIVE_COMPONENT` decimal(10,2) DEFAULT NULL,
 `TAKE_FROM_SYSTEM` decimal(10,2) DEFAULT NULL,
 `FEED_INTO_SYSTEM` decimal(10,2) DEFAULT NULL,
 `REGULATION_STATE` tinyint(1) DEFAULT NULL,
 `HOUR` int(2) DEFAULT NULL,
 PRIMARY KEY (`imbalanceprice_id`),
 KEY `DATE` (`DATE`,`PERIOD_FROM`,`PERIOD_UNTIL`)
) ENGINE=MyISAM AUTO_INCREMENT=117427 DEFAULT CHARSET=latin

CREATE TABLE `powerload` (
 `powerload_id` int(11) NOT NULL AUTO_INCREMENT,
 `EAN` varchar(18) DEFAULT NULL,
 `DATE` date DEFAULT NULL,
 `PERIOD_FROM` time DEFAULT NULL,
 `PERIOD_UNTIL` time DEFAULT NULL,
 `POWERLOAD` int(11) DEFAULT NULL,
 PRIMARY KEY (`powerload_id`)
) ENGINE=MyISAM AUTO_INCREMENT=61039 DEFAULT CHARSET=latin

现在运行此查询时:

SELECT  i.DATE, i.PERIOD_FROM, i.TAKE_FROM_SYSTEM, i.FEED_INTO_SYSTEM,
        a.PRICE, p.POWERLOAD, sum(a.PRICE * p.POWERLOAD)
    FROM  imbalanceprice i, apxprice a, powerload p
    WHERE  i.DATE = a.DATE
      and  i.DATE = p.DATE
      AND  i.PERIOD_FROM >= a.PERIOD_FROM
      and  i.PERIOD_FROM = p.PERIOD_FROM
      AND  i.PERIOD_FROM < a.PERIOD_UNTIL
      AND  i.DATE >= '2018-01-01'
      AND  i.DATE <= '2018-01-31'
    group by  i.DATE

我已经用 explain 运行查询并得到以下结果: Select_type, all simple partitions all null possible keys a,p = null i = DATE Key a,p = null i = DATE key_len a,p = null i = 8 ref a,p = null i = timeseries.a.DATE,timeseries.p.PERIOD_FROM 行 a = 28727 p = 61038 i = 1 过滤 a = 100 p = 10 i = 100 额外:使用 where 使用临时使用 filesort b extra: using where using join buffer (block nested loop) c extra: null

我最好运行一个更复杂的查询,针对整年并按月分组,例如包含所有价格表。但是,这太慢了。我已经在每个表中编制了索引:DATE、PERIOD_FROM、PERIOD_UNTIL。计算结果可能不会改变,在这种情况下,两米的季度小时消耗乘以小时价格。

【问题讨论】:

  • 您应该考虑学习和使用现代连接语法。
  • A) 使用JOIN。 B) 使用EXPLAIN
  • 从所涉及的条件来看,似乎ap 在与i 的关系之外是无关的。请记住,如果某个特定的i 有两个a 和三个p,那么您将获得该i 的六个结果; i 及其相关的 ap 记录的每个组合。另外值得注意的是,(DATE, PERIOD_FROM, PERIOD_UNTIL) 上的索引与每个字段上的单独索引不同;并且 MySQL 只会在单个查询中使用每个表中的一个 (这就是为什么通常最好只为您的问题中的表包含实际的完整 CREATE。).
  • 请发布 EXPLAIN SELECT SQL_NO_CACHE ........的文本结果以供分析以及查询中涉及的 SHOW CREATE TABLE table_name(s) 和 SHOW INDEX FROM table_name(s)。
  • 请学习本站的格式化工具; EXPLAIN 不可读。

标签: mysql performance indexing


【解决方案1】:

“明确地说,”你首先应该看的是索引。

WHERE i.DATE = a.DATE ... 等子句被明确地称为INNER JOIN,,SQL 引擎需要能够“立即”定位匹配的行。 (也就是说,不用看整个表!)

  • 仅供参考: 就像现实生活中的任何索引一样——如果我们还有这样的东西,我将在这里谈论“图书馆卡片目录”——索引将有助于“等于”和“小于/大于”比”查询。索引将计算机直接带到数据中的特定点,无论是“命中”还是“未遂事件”。

最后,EXPLAIN 动词非常有用:将这个词放在您的查询前面,SQL 引擎应该准确地“向您解释”如何执行您的查询。 (SQL 引擎会查看数据库的结构来做出决定。)虽然EXPLAIN 的输出是... (heh) ...“不完全标准化”,它帮助您查看计算机是否认为它需要做一些非常浪费时间的事情才能提供您的答案。

【讨论】:

  • 感谢您的反馈。我已经阅读了有关连接的信息,但是,从我在线阅读的内容来看,这不会加快查询速度。这将使查询对其他人更具可读性。我将尝试将查询转换为连接查询。
  • 关于“解释”功能,这对我来说是新的。我用解释运行查询并得到以下结果: Select_type, all simple partitions all null possible keys a,p = null i = DATE Key a,p = null i = DATE key_len a,p = null i = 8 ref a ,p = null i = timeseries.a.DATE,timeseries.p.PERIOD_FROM 行 a = 28727 p = 61038 i = 1 过滤 a = 100 p = 10 i = 100 额外:使用 where 使用临时使用文件排序 b 额外:使用where using join buffer (block nested loop) c extra: null
猜你喜欢
  • 2016-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多