【问题标题】:Same mysql queries in two similar databases in the same machine have different perfomance同一台机器的两个相似数据库中的相同mysql查询性能不同
【发布时间】:2015-07-31 03:10:02
【问题描述】:

我有两个数据库,一个用于开发,一个用于暂存,它们也在同一台机器上。我在查询两个表时遇到问题。这是表格的架构

表 1 架构:

Table: import_schedule_t
Create Table: CREATE TABLE `import_schedule_t` (
  `id` int(11) NOT NULL,
  `theater_id` int(11) NOT NULL,
  `movie_code` varchar(20) NOT NULL,
  `start_time` datetime NOT NULL,
  `end_time` datetime NOT NULL,
  `pc_url` varchar(250) NOT NULL,
  `mb_url` varchar(250) NOT NULL,
  `url_type` int(11) DEFAULT '0',
  `active` int(11) DEFAULT '1',
  `intime` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `utime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `schedule_date` datetime NOT NULL,
  `movie_name` text NOT NULL,
  `screen_name` text NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8

和表 2 架构:

 Table: wp_postmeta
 Create Table: CREATE TABLE `wp_postmeta` (
   `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   `post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
   `meta_key` varchar(255) DEFAULT NULL,
   `meta_value` longtext,
   PRIMARY KEY (`meta_id`),
   KEY `post_id` (`post_id`),
   KEY `meta_key` (`meta_key`(191))
 ) ENGINE=MyISAM AUTO_INCREMENT=1399270 DEFAULT CHARSET=utf8

这两个表都存在于我提到的两个数据库中。当我尝试运行此查询时:

 SELECT DISTINCT movie_code,post_id 
 FROM import_schedule_t 
 INNER JOIN wp_postmeta 
 ON wp_postmeta.meta_value = import_schedule_t.movie_code 
 AND wp_postmeta.meta_key='update_movie_id' 
 WHERE DATE_FORMAT(start_time, '%Y-%m-%d')>= DATE_FORMAT(NOW(),'%Y-%m-%d')

dev 数据库会在 20 秒内完成查询,但 staging 数据库只会运行 1.4 秒。

这是一个示例数据: wp_postmeta 表

+---------+---------+-----------------+------------+
| meta_id | post_id | meta_key        | meta_value |
+---------+---------+-----------------+------------+
|   45150 |   74572 | update_movie_id | 74572      |
+---------+---------+-----------------+------------+

import_schedule_t 表(省略部分字段)

+--------+------------+---------------------+---------------------+
| id     | movie_code | start_time          | end_time            |
+--------+------------+---------------------+---------------------+
| 120884 | 74572      | 2015-07-04 12:50:00 | 2015-07-04 15:05:00 |
+--------+------------+---------------------+---------------------+

我已经尝试查看索引并优化表,但没有成功,开发数据库上的查询时间仍然是 20 秒。

EXPLAIN EXTENDED on dev

+----+-------------+-------------------+------+---------------+------+---------+------+---------+----------+--------------------------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra                          |
+----+-------------+-------------------+------+---------------+------+---------+------+---------+----------+--------------------------------+
|  1 | SIMPLE      | import_schedule_t | ALL  | NULL          | NULL | NULL    | NULL |   23597 |   100.00 | Using where; Using temporary   |
|  1 | SIMPLE      | wp_postmeta       | ALL  | NULL          | NULL | NULL    | NULL | 1461731 |   100.00 | Using where; Using join buffer |
+----+-------------+-------------------+------+---------------+------+---------+------+---------+----------+--------------------------------+

解释在暂存时扩展

+----+-------------+-------------------+------+---------------+------+---------+------+---------+----------+--------------------------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra                          |
+----+-------------+-------------------+------+---------------+------+---------+------+---------+----------+--------------------------------+
|  1 | SIMPLE      | import_schedule_t | ALL  | NULL          | NULL | NULL    | NULL |    9311 |   100.00 | Using where; Using temporary   |
|  1 | SIMPLE      | wp_postmeta       | ALL  | NULL          | NULL | NULL    | NULL | 1461384 |   100.00 | Using where; Using join buffer |
+----+-------------+-------------------+------+---------------+------+---------+------+---------+----------+--------------------------------+

【问题讨论】:

  • 请取消标记'sql server'
  • 您是否在两台服务器上运行相同版本的 MySQL?也许表上的数据量有很大差异?你的查询在我看来没问题。我确实认为格式化 where 子句的日期是不必要的。 start_time >= date_time 应该也能正常工作。
  • 好吧,基本上是相同的版本,因为它们在同一台机器上。数据大小的差异似乎不是原因,因为两个数据库都包含 130 万条记录。我还在看索引。注意 date_format,谢谢
  • 您能否对查询运行 EXPLAIN EXTENDED 并向我们展示结果。我不完全确定这一点,但它可能有助于将您的 wp_postmeta.meta_key='update_movie_id' 从 ON 子句移到 WHERE 子句中。

标签: mysql database


【解决方案1】:

如果两个数据库运行在同一台机器上,使用相同的 MySQL 版本,在同一个硬盘驱动器中,具有完全相同的结构和数据,那么这可能是操作系统级别的碎片问题。关闭服务器并对磁盘进行碎片整理。

附带说明:不要将日期作为字符串进行比较,因为日期是数据库内部的数字,并且它们的比较效率更高(WHERE start_time >= curdate())。 如果您为某些字段(如“活动”字段)定义较小的整数,也可以节省一些存储空间。 int 是 4 字节的数字,而 tinyint 是 1 字节。

【讨论】:

  • hmmm 好的,如果操作系统级别有问题,请询问 dc 工作人员。注意到 curdate()。
【解决方案2】:

抱歉,无法发表评论,因为我没有足够的声誉,但是,我希望开发系统的表中有更多的数据。

另一方面,您不应该使用 DATE_FORMAT - 我猜想这会将您的日期转换为比较低效的字符串。日期只是整数(MySQL 内部的),因此它们可以在一个周期内进行比较。字符串比较很容易是 1000(或更多)个周期。您可能还应该索引 start_time 字段以节省扫描表的时间。

只要您有一个需要 20 秒的查询,您就应该怀疑自己做错了什么! MySQL 可以在 20 秒内做很多事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 2014-08-15
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多