簡體   English   中英

PDO比mysql查詢慢得多?

[英]PDO much slower than mysql query?

我在PHP中使用PDO對象來運行MYSQL查詢,我一直在嘗試處理查詢以加快它的速度。 查詢如下,如我的PHP文件中所示:

$query = 
"SELECT SQL_NO_CACHE f.position, s.item_id, s.item_type, s.title, s.caption, s.date
FROM apiv2.search_all s 
INNER JOIN apiv2.tags t 
USING(item_id, item_type) 
LEFT JOIN apiv2.featured f 
ON t.item_id = f.item_id AND t.item_type = f.item_type AND f.feature_type = :id 
WHERE t.tag = 'FeaturedContent'
ORDER BY position IS NULL, position ASC, date";

$mysql_vars[':id'] = $id;
$stmt = $connection->prepare($query);
$stmt->execute($vars);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

此查詢的運行方式有很大不同,具體取決於我是否包含ORDER BY子句,但僅限於MYSQL控制台:

 - MYSQL Console with ORDER BY: 1.07 sec
    - starting  0.000141
    - Opening tables    0.001416
    - System lock   0.000003
    - Table lock    0.000007
    - init  0.000021
    - checking permissions  0.000001
    - checking permissions  0.000036
    - optimizing    0.000027
    - statistics    0.000027
    - preparing 0.000015
    - Creating tmp table    0.003440
    - executing 0.000001
    - Copying to tmp table  1.050029
    - Sorting result    0.013097
    - Sending data  0.000295
    - end   0.000002
    - removing tmp table    0.002045
    - end   0.000003
    - query end 0.000002
    - freeing items 0.000331
    - logging slow query    0.000002
    - cleaning up   0.000007
 - MYSQL Console unordered output: .0053 sec
    - starting  0.000076
    - Opening tables    0.001506
    - System lock   0.000002
    - Table lock    0.000005
    - init  0.000015
    - checking permissions  0.000001
    - checking permissions  0.000022
    - optimizing    0.000012
    - statistics    0.000021
    - preparing 0.000011
    - executing 0.000001
    - Sending data  0.002895
    - end   0.000002
    - query end 0.000001
    - freeing items 0.000078
    - logging slow query    0.000000
    - cleaning up   0.000002
 - PDO Prepared stmt ORDER BY: 1.18 sec
    - 'Status' => 'starting', 'Duration' => '0.000147'
    - 'Status' => 'Opening tables', 'Duration' => '0.000784'
    - 'Status' => 'System lock', 'Duration' => '0.000004'
    - 'Status' => 'Table lock', 'Duration' => '0.000007'
    - 'Status' => 'init', 'Duration' => '0.000017'
    - 'Status' => 'checking permissions', 'Duration' => '0.000002'
    - 'Status' => 'checking permissions', 'Duration' => '0.000028'
    - 'Status' => 'optimizing', 'Duration' => '0.000018'
    - 'Status' => 'statistics', 'Duration' => '0.000026'
    - 'Status' => 'preparing', 'Duration' => '0.000014'
    - 'Status' => 'Creating tmp table', 'Duration' => '0.002112'
    - 'Status' => 'executing', 'Duration' => '0.000001'
    - 'Status' => 'Copying to tmp table', 'Duration' => '1.033056'
    - 'Status' => 'Sorting result', 'Duration' => '0.013759'
    - 'Status' => 'Sending data', 'Duration' => '0.073144'
    - 'Status' => 'end', 'Duration' => '0.000003'
    - 'Status' => 'removing tmp table', 'Duration' => '0.001999'
    - 'Status' => 'end', 'Duration' => '0.000004'
    - 'Status' => 'query end', 'Duration' => '0.000007'
    - 'Status' => 'freeing items', 'Duration' => '0.000118'
    - 'Status' => 'logging slow query', 'Duration' => '0.000001'
    - 'Status' => 'cleaning up', 'Duration' => '0.000003'
 - PDO Prepared stmt unordered output: 1.06 sec
    - 'Status' => 'starting', 'Duration' => '0.000074'
    - 'Status' => 'Opening tables', 'Duration' => '0.001364'
    - 'Status' => 'System lock', 'Duration' => '0.000004'
    - 'Status' => 'Table lock', 'Duration' => '0.000007'
    - 'Status' => 'init', 'Duration' => '0.000017'
    - 'Status' => 'checking permissions', 'Duration' => '0.000001'
    - 'Status' => 'checking permissions', 'Duration' => '0.000026'
    - 'Status' => 'optimizing', 'Duration' => '0.000015'
    - 'Status' => 'statistics', 'Duration' => '0.000027'
    - 'Status' => 'preparing', 'Duration' => '0.000013'
    - 'Status' => 'executing', 'Duration' => '0.000002'
    - 'Status' => 'Sending data', 'Duration' => '1.048216'
    - 'Status' => 'end', 'Duration' => '0.000003'
    - 'Status' => 'query end', 'Duration' => '0.000001'
    - 'Status' => 'freeing items', 'Duration' => '0.000122'
    - 'Status' => 'logging slow query', 'Duration' => '0.000001'
    - 'Status' => 'cleaning up', 'Duration' => '0.000003' 
 - MYSQL functions from PHP unordered: 1.09 sec
    - 'Status' => 'starting', 'Duration' => '0.000109'
    - 'Status' => 'checking permissions', 'Duration' => '0.000002'
    - 'Status' => 'checking permissions', 'Duration' => '0.000001'
    - 'Status' => 'checking permissions', 'Duration' => '0.000004'
    - 'Status' => 'Opening tables', 'Duration' => '0.002101'
    - 'Status' => 'System lock', 'Duration' => '0.000004'
    - 'Status' => 'Table lock', 'Duration' => '0.000009'
    - 'Status' => 'init', 'Duration' => '0.000032'
    - 'Status' => 'checking permissions', 'Duration' => '0.000003'
    - 'Status' => 'checking permissions', 'Duration' => '0.000057'
    - 'Status' => 'optimizing', 'Duration' => '0.000033'
    - 'Status' => 'statistics', 'Duration' => '0.000065'
    - 'Status' => 'preparing', 'Duration' => '0.000032'
    - 'Status' => 'executing', 'Duration' => '0.000005'
    - 'Status' => 'Sending data', 'Duration' => '1.000079'
    - 'Status' => 'end', 'Duration' => '0.000005'
    - 'Status' => 'query end', 'Duration' => '0.000002'
    - 'Status' => 'freeing items', 'Duration' => '0.000300'
    - 'Status' => 'logging slow query', 'Duration' => '0.000001'
    - 'Status' => 'cleaning up', 'Duration' => '0.000007'
 - MYSQL functions from PHP w/ ORDER BY: 1.09 sec
    - 'Status' => 'starting', 'Duration' => '0.000148'
    - 'Status' => 'checking permissions', 'Duration' => '0.000001'
    - 'Status' => 'checking permissions', 'Duration' => '0.000001'
    - 'Status' => 'checking permissions', 'Duration' => '0.000001'
    - 'Status' => 'Opening tables', 'Duration' => '0.000559'
    - 'Status' => 'System lock', 'Duration' => '0.000002'
    - 'Status' => 'Table lock', 'Duration' => '0.000006'
    - 'Status' => 'init', 'Duration' => '0.000019'
    - 'Status' => 'checking permissions', 'Duration' => '0.000001'
    - 'Status' => 'checking permissions', 'Duration' => '0.000030'
    - 'Status' => 'optimizing', 'Duration' => '0.000018'
    - 'Status' => 'statistics', 'Duration' => '0.000025'
    - 'Status' => 'preparing', 'Duration' => '0.000015'
    - 'Status' => 'Creating tmp table', 'Duration' => '0.001828'
    - 'Status' => 'executing', 'Duration' => '0.000001'
    - 'Status' => 'Copying to tmp table', 'Duration' => '0.958071'
    - 'Status' => 'Sorting result', 'Duration' => '0.013502'
    - 'Status' => 'Sending data', 'Duration' => '0.088148'
    - 'Status' => 'end', 'Duration' => '0.000003'
    - 'Status' => 'removing tmp table', 'Duration' => '0.002037'
    - 'Status' => 'end', 'Duration' => '0.000003'
    - 'Status' => 'query end', 'Duration' => '0.000001'
    - 'Status' => 'freeing items', 'Duration' => '0.000112'
    - 'Status' => 'logging slow query', 'Duration' => '0.000001'
    - 'Status' => 'cleaning up', 'Duration' => '0.000004'

解釋:

與訂購

|-id-|-select_type-|-table----|-type---|-possible_keys--------|-key-----------------|-key_len-|-ref-------------------------------------|-rows--|-Extra
|-1--|-SIMPLE------|-s--------|-ALL----|-PRIMARY,search_index-|-NULL----------------|-NULL----|-NULL------------------------------------|-92166-|-Using temporary; Using filesort
|-1--|-SIMPLE------|-tags-----|-eq_ref-|-PRIMARY--------------|-PRIMARY-------------|-426-----|-apiv2.s.item_id,apiv2.s.item_type,const-|-1-----|-Using where; Using index
|-1--|-SIMPLE------|-featured-|-ref----|-type_position_index--|-type_position_index-|-62------|-const-----------------------------------|-3-----|-Using index

沒有訂購

|-id-|-select_type-|-table----|-type---|-possible_keys--------|-key-----------------|-key_len-|-ref-------------------------------------|-rows--|-Extra
|-1--|-SIMPLE------|-s--------|-ALL----|-PRIMARY,search_index-|-NULL----------------|-NULL----|-NULL------------------------------------|-88346-|-
|-1--|-SIMPLE------|-tags-----|-eq_ref-|-PRIMARY--------------|-PRIMARY-------------|-426-----|-apiv2.s.item_id,apiv2.s.item_type,const-|-1-----|-Using where; Using index
|-1--|-SIMPLE------|-featured-|-ref----|-type_position_index--|-type_position_index-|-62------|-const-----------------------------------|-3-----|-Using index

表:search_all

CREATE TABLE `search_all` (  
  `item_id` varchar(20) NOT NULL DEFAULT '',  
  `item_type` varchar(20) NOT NULL DEFAULT '',  
  `title` varchar(255) DEFAULT NULL,  
  `caption` text,  
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  
  PRIMARY KEY (`item_id`,`item_type`),  
  UNIQUE KEY `search_index` (`item_id`,`item_type`,`date`),  
  KEY `date_index` (`date`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8;  


|-id-|-select_type-|-table------|-type-|-possible_keys-|-key--|-key_len-|-ref--|-rows--|-Extra
|-1--|-SIMPLE------|-search_all-|-ALL--|-NULL----------|-NULL-|-NULL----|-NULL-|-74785-|-

表:標簽

CREATE TABLE `tags` (  
  `tag` varchar(100) NOT NULL DEFAULT '',  
  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  
  `item_id` varchar(20) NOT NULL DEFAULT '',  
  `item_type` varchar(20) NOT NULL DEFAULT '',  
  PRIMARY KEY (`item_id`,`item_type`,`tag`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8;  


|-id-|-select_type-|-table-|-type--|-possible_keys-|-key-----|-key_len-|-ref--|-rows---|-Extra
|-1--|-SIMPLE------|-tags--|-index-|-NULL----------|-PRIMARY-|-426-----|-NULL-|-197400-|-Using index

表:特色

CREATE TABLE `featured` (  
  `position` int(10) NOT NULL DEFAULT '0',  
  `item_type` varchar(20) NOT NULL DEFAULT '',  
  `item_id` varchar(20) NOT NULL DEFAULT '',  
  `feature_type` varchar(20) NOT NULL DEFAULT '',  
  PRIMARY KEY (`position`,`item_type`,`item_id`,`feature_type`),  
  KEY `type_position_index` (`feature_type`,`position`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8;  


|-id-|-select_type-|-table----|-type--|-possible_keys-|-key-----------------|-key_len-|-ref--|-rows-|-Extra
|-1--|-SIMPLE------|-featured-|-index-|-NULL----------|-type_position_index-|-66------|-NULL-|-13---|-Using index

為什么PDO中的無序或PHP中的MSQL沒有區別? 有什么方法可以讓它更快嗎?

除非您的訂單是針對索引列的,並且優化器認為使用索引是個好主意,否則“ORDER BY”將導致排序,這會為任何大小的任何結果集花費大量時間和資源。

PDO版本花費更長時間的原因是您的腳本消耗的行比SQLServer可以提供的行慢,因此數據庫正在等待您的程序。 當您使用解釋語言和對行結果進行大量操作的API時,這只是預期的。 這種延遲“發送數據”比排序的開銷大得多(0.75秒和1.04秒)。

請注意,慢速檢索由order by復雜化。 在無序SQL的情況下,行將在選擇后立即發送。 在有序選擇的情況下,將選擇所有行,然后在發送第一個結果行之前對其進行排序。

您能否發布表定義(字段,字段類型等)?

我會在第一次添加一個簡單的索引datesearch_all

一個簡單的索引tagtags

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM