我使用Zend框架和頁面加載在生產服務器上比在開發一個慢得多的一個站點工作的14倍。經過一些挖掘和分析(使用xdebug)之後,我發現PDOStatement-> execute調用在生產服務器上運行11 134毫秒,在開發服務器上運行780毫秒。PDOStatement->執行較慢的生產服務器上比開發服務器
數據庫是兩臺服務器上是相同的,MySQL的版本是兩個服務器(32年5月5日)和MySQL配置在相同的兩個服務器上相同的(下降到在my.cnf的線)。兩臺服務器也都運行Ubuntu 12.04.2 LTS,儘管開發服務器與生產服務器相比具有額外的軟件。我能想到的唯一區別是dev服務器在SSD上運行,而生產服務器運行RAID 0中的兩個常規SATA驅動器。然而,在phpMyAdmin中運行查詢大概是同一時間(0.0003-0.0005秒,儘管我不信任phpMyAdmin執行時間報告)。
這裏是我運行的查詢:
$query = "SET @rank = 0";
$statement = $db->query($query);
$query = "SET @previous_result = -1";
$statement = $db->query($query);
$query = "
SELECT
@group_id := IFNULL(g.id, -1)
FROM
`branch_statistics` bs
JOIN
branch_to_wave btw ON bs.branch_to_wave_id = btw.id
JOIN
branch_to_group btg ON bs.branch_id = btg.branch_id
JOIN
`group` g ON btg.group_id = g.id
WHERE
btw.wave_id = $wave_id AND bs.branch_id = $branch_id";
$statement = $db->query($query);
$query = "DROP TABLE IF EXISTS group_members";
$statement = $db->query($query);
$query = "CREATE TEMPORARY TABLE group_members (id INT PRIMARY KEY)";
$statement = $db->query($query);
$query = "DROP TABLE IF EXISTS group_members2";
$statement = $db->query($query);
$query = "CREATE TEMPORARY TABLE group_members2 (id INT PRIMARY KEY)";
$statement = $db->query($query);
$query = "
INSERT INTO
group_members
SELECT
btw.id
FROM
branch_to_wave btw
JOIN
branch_to_group btg ON btw.branch_id = btg.branch_id
WHERE
btw.wave_id = $wave_id AND
btg.group_id = @group_id
GROUP BY
btw.id";
$statement = $db->query($query);
$query = "INSERT INTO group_members2 SELECT id FROM group_members";
$statement = $db->query($query);
$query = "
SELECT @number_of_results :=
COUNT(result)
FROM
(
SELECT
ROUND(points/maximum_points, 4) as result
FROM
`branch_statistics` bs
JOIN
group_members2 gm2 ON gm2.id = bs.branch_to_wave_id
GROUP BY
result
) results
";
$statement = $db->query($query);
$query = "
EXPLAIN SELECT
*,
@number_of_results as number_of_results
FROM
(
SELECT
*,
IF(@previous_result != result, @rank := @rank + 1, @rank) as rank,
@previous_result := result
FROM
(
SELECT
bs.branch_id,
ROUND(points/maximum_points, 4) as result,
(
SELECT
AVG(ROUND(points/maximum_points, 4)) as average
FROM
`branch_statistics` bs
JOIN
group_members2 gm2 ON gm2.id = bs.branch_to_wave_id
) as average
FROM
`branch_statistics` bs
JOIN
group_members gm ON gm.id = bs.branch_to_wave_id
GROUP BY
bs.branch_id
ORDER BY
result DESC
) complete
) results
WHERE branch_id = $branch_id
";
$statement = $db->query($query);
$statement->setFetchMode(Zend_Db::FETCH_NUM);
$results = $statement->fetchAll();
我不知道,如果服務器規格是相關的,但在這裏,他們在任何情況下:
生產服務器:
英特爾(R)核心(TM)2雙核CPU E7500 @ 2.93GHz的與3.4G b RAM
開發服務器(運行在以下硬件的虛擬機,與其他的虛擬機5-6):
AMD FX(TM)-8120八核心處理器與RAM的3Gb
所以我的問題是這樣的:我怎麼能找出是什麼原因造成這種差異?
編輯#1(2013年8月16日@ 11:23):對於那些不熟悉與Zend框架,這裏是調用堆棧導致PDOStatement->執行:
- $ db-> query($ query);
- Zend_Db_Adapter_Pdo_Abstract->查詢
- Zend_Db_Statement->執行
- Zend_Db_Statement_Pdo->執行
- PDOStatement->執行
編輯#2(2013年8月16日@ 13 :09):這裏是兩臺機器的性能分析結果。
Status Duration DEV Duration PROD
starting 0.000032 0.000010
Waiting for query cache lock 0.000010 0.000006
checking query cache for query 0.000183 0.000074
checking permissions 0.000010 0.000007
checking permissions 0.000009 0.000006
checking permissions 0.000009 0.000006
checking permissions 0.000011 0.000007
Opening tables 0.000030 0.000017
System lock 0.000140 0.000063
optimizing 0.000016 0.000010
statistics 0.000035 0.000016
preparing 0.000020 0.000011
Creating tmp table 0.000028 0.000015
executing 0.000009 0.000006
Copying to tmp table 0.000424 0.000133
Sorting result 0.000039 0.000017
Sending data 0.000015 0.000008
optimizing 0.000014 0.000009
statistics 0.000022 0.000012
preparing 0.000019 0.000010
executing 0.000011 0.000007
Sending data 0.000171 0.000110
optimizing 0.000006 0.000007
statistics 0.000006 0.000008
preparing 0.000006 0.000007
executing 0.000004 0.000006
Sending data 0.000042 0.000035
removing tmp table 0.000007 0.000009
Sending data 0.000006 0.000008
init 0.000011 0.000013
optimizing 0.000005 0.000008
statistics 0.000006 0.000008
preparing 0.000006 0.000009
executing 0.000004 0.000006
Sending data 0.000016 0.000019
end 0.000005 0.000007
query end 0.000005 0.000007
closing tables 0.000004 0.000006
removing tmp table 0.000005 0.000007
closing tables 0.000004 0.000006
removing tmp table 0.000006 0.000007
closing tables 0.000006 0.000008
freeing items 0.000013 0.000275
logging slow query 0.000004 0.000007
cleaning up 0.000006 0.000007
我還測試mysqlslap,發現一些非常有趣的結果,隨後(時間是平均查詢時間)。您可以看到,儘管同時進行多個同時查詢確實會增加平均查詢時間,但與開發服務器相比,同一查詢在生產服務器上的速度仍然低24倍。
我不太明白如何在phpMyAdmin中運行查詢可以花費0.0005秒,而使用mysqlslap的相同查詢需要0.299秒,但我懷疑存在我的問題的核心。
Mysqlslap settings Dev Prod
iterations = 10, concurrency = 50 1.253 14.129
iterations = 10, concurrency = 25 0.513 7.153
iterations = 10, concurrency = 10 0.141 3.133
iterations = 10, concurrency = 1 0.014 0.299
你有沒有看每條語句督促服務器上執行計劃相比,開發服務器? mySQL中的執行計劃可能會顯示您缺少索引,生產中的數據與dev不同,或者使用了錯誤的索引導致延遲。但直到您將其縮小到個人陳述的範圍內時,這裏的任何人都難以排除故障。 – xQbert
性能降低很容易從這裏猜到,但大多數情況下,你必須看幾個關鍵的東西。假設你的開發環境和產品環境中有相同的模式,請查看數據大小。在你的工具上使用mysqlslap類似工具dev機器來檢查重負載下的性能,因爲dev env通常不會像您的prod機器那樣做很多工作。 – WordsWorth
您是否嘗試過沒有PDO的相同查詢? –