2017-03-17 69 views
1

我正在將PHP應用程序從MSSQL服務器遷移到MySQL,並且我堅持使用MSSQL Server持續0.5秒和MySQL 50秒的簡單查詢。有任何想法嗎?指標?服務器配置? MySQL服務器硬件與MSSQL服務器相同或更好。與大表簡單連接的MySQL性能問題

表結構

兩者都是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。

這只是一個示例,最終目標是使用其他日期過濾器/交叉點等進行更大的查詢。

解釋計劃從SQL Server

Explain Plan Query on MySQL

執行計劃: Execution plan from SQL Server Query on SQL Server

配置,硬件,...

@@ innodb_buffer_pool_size:2147483648
SELECT()版本:5.7.17-0ubuntu0.16.04.1
Profiling of the query(CSV文件)
Procedure Analyse()(XLS文件)
my.cnf
系統:
 的VMware虛擬平臺
 英特爾(R)至強(R)CPU E5530 @ 2.40GHz的
  4GiB DIMM EDO DRAM
 的Ubuntu 16.04.2 LTS(Linux的GT 4.4.0-66泛型x86_64的)

+0

吊。。我知道想要得到一個更便宜或開放的數據庫,但這些日子是Postgresql,而不是MySql。自2004年以來,MySql並沒有跟上步伐,Sql Server,Oracle和Postgresql取得了進展。它不再是真正的現代數據庫引擎:沒有CTE(遞歸或其他),沒有窗口函數,沒有橫向連接/應用,沒有完全連接等等。 –

+0

這可能是一個內存問題,用'SELECT @@ innodb_buffer_pool_size;'編輯你的問題,並添加解釋計劃 – Mihai

+0

我敢打賭,如果你使用'INNER JOIN'而不是'LEFT JOIN',那麼會更快。你是否需要在'tb2'中統計'tb1'中沒有任何匹配的行? – Barmar

回答

0

有很多事情可能會在這裏發生,但鑑於您正在從一種數據庫類型轉移到另一種數據庫,它可能是一個新的服務器。考慮到這一點,可能只需要進行一些基本的服務器調整即可。例如,MySql的緩衝池必須手動設置,否則它不會使用服務器中的大部分內存。這樣做了嗎?

+0

這兩張表 –

+0

中的索引是否已經存在,請發佈我們對您的陳述的解釋,但它看起來一切正常。你使用哪個引擎。 –

+0

是的,我看到了那麼晚。重新解答答案。 –

1

這不是答案

我創建隨機數據樣本2表(我知道它的不一樣),每個50萬行和測試您的查詢。這將需要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) ; 
+0

我在第一篇文章中添加了所有信息。我試過了你最後的查詢,只需要800ms!爲什麼??? – Dimas

+0

爲什麼不能:-),好於50秒。我會在稍後回答,現在我去看望某人。當我回來時,我會閱讀你的文章,抱歉延遲 –

+0

我的一個很大的錯誤:在tb1'nec'字段可能爲空。事實上,有很多行'nec'= NULL。實際上,原始查詢/ SELECT試圖放棄NULL,添加條件tb1.nec IS NOT NULL,但這沒有幫助。 – Dimas