与大表

时间:2017-03-17 19:02:14

标签: mysql performance join

我正在将PHP应用程序从MSSQL Server迁移到MySQL,并且我遇到了一个简单的查询,MSSQL Server持续0.5秒,MySQL持续50秒。有任何想法吗?指标?服务器配置? MySQL服务器硬件与MSSQL服务器相同或更好。

表格结构

两者都是InnoDB:

CREATE TABLE `tb1` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `nec` INT(11),
    `start_date` DATETIME(6) NOT NULL,
    `end_date` DATETIME(6) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `IX_nec` (`nec`)
);

CREATE TABLE `tb2` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `nec` INT(11) NOT NULL,
    `start_date` DATETIME(6) NOT NULL,
    `end_date` DATETIME(6) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `IX_nec` (`nec`)
);

表格。 Tb1有大约300.000行,tb2大约有400.000。

选择

SELECT count(1)
FROM tb2
LEFT JOIN tb1 ON tb1.nec = tb2.nec

结果大约是180.000.000。

这只是一个示例,最终目标是使用其他日期过滤器/交叉点等更大的查询。

解释计划

Explain Plan Query on MySQL

SQL Server的执行计划: Execution plan from SQL Server Query on SQL Server

配置,硬件......

@@ innodb_buffer_pool_size:2147483648
SELECT version():5.7.17-0ubuntu0.16.04.1
Profiling of the query(CSV文件)
Procedure Analyse()(XLS档案)
my.cnf
系统:
VMware虚拟平台
英特尔(R)Xeon(R)CPU E5530 @ 2.40GHz
4GiB DIMM DRAM EDO
Ubuntu 16.04.2 LTS(Linux gt 4.4.0-66-generic x86_64)

2 个答案:

答案 0 :(得分:1)

这不是答案

我创建了2个包含随机数据的样本表(我知道它们不相同),每个500000行并测试您的查询。这将需要1,1秒。所以我几乎可以肯定这是一个配置或硬件问题。所以我将使用更多信息。你能否我发布查询的输出

1)SELECT VERSION();

2)此

的输出
SET PROFILING=ON;

SELECT count(1)
FROM tb2
LEFT JOIN tb1 USING(nec);

SHOW PROFILE ALL;
SET PROFILING=OFF;

3)你的my.cnf

4)有关硬件和操作系统的一些信息

您也可以查看此查询。我的服务器只需要500毫秒

SELECT sum(IF(s IS NULL,1,s)) AS cnt
FROM tb2
LEFT JOIN 
  (SELECT DISTINCT nec, SUM(1) AS s FROM tb1 GROUP BY nec) tmp USING (nec) ;

答案 1 :(得分:0)

这里可能会发生很多事情,但鉴于您正在从一种数据库类型转移到另一种数据库类型,它可能是一个新的服务器。考虑到这一点,可能只需要进行一些基本的服务器调整。例如,必须手动设置MySql的缓冲池,否则它将不会占用服务器中的大部分内存。这已经完成了吗?