2011-06-22 22 views
15

MYSQL sorgularını çalıştırmak için PHP'de bir PDO nesnesi kullanıyorum ve hızlandırmak için bir sorgu üzerinde çalışmaya çalışıyorum. Sorgu benim PHP dosyasında görüldüğü gibi, aşağıdaki gibidir:

PDO, mysql sorgusundan daha mı yavaş?

$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); 

Bu sorgu önemli ölçüde farklı ben ORDER BY deyimini dahil olmasına bağlı, fakat sadece MYSQL konsolunda çalışır:

- 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' 

açıklanmaktadır:

|-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 
düzenlense 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-|- 

TABLO: etiketlerini

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 

TABLO:

|-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 

TABLO SİPARİŞ OLMADAN

özellikli
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 

Neden PDO veya MSQL PHP'den gelen sıralamalar arasında fark yok? Daha hızlı yapmamın bir yolu var mı?

+3

Tablo tanımlarını (dizinler dahil) ve sorgunun (EXPLAIN) yürütme planını yazın. –

+0

Gerçekten bunu yeniden üretebiliyor musunuz? "Veri Gönderme" son örnekte çok fazla zaman tüketiyor gibi görünüyor. Belki de sadece bir "gecikme" veya bir önbellekleme sorunu. – KingCrunch

+1

Zamanın, profildeki her adımın başında kontrol edildiğine inanıyorum, yani uzun olanları, önceki adımın kötü bir şekilde gözden geçirilmesi anlamına gelir; bu, tüm parmakları 'yürütme' adımında işaret eder. – Ripptor

cevap

5

Siparişiniz dizine eklenmiş bir sütun için yapılmadıkça ve optimize edici, dizinin bir "ORDER BY" parametresinin kullanılması için iyi bir fikir olduğunu düşünürse, herhangi bir boyuttaki sonuç kümesi için önemli zaman ve kaynak gerektiren bir türle sonuçlanır.

PDO sürümünün daha uzun sürmesinin nedeni, komut dosyanızın SQLServer'dan daha yavaş satırlar tüketmesidir, bu nedenle Veritabanı programınızı bekler. Yorumlanan bir dil ve satır sonucunun önemli miktarda manipülasyonunu yapan bir API kullandığınız için bu sadece beklenen bir durumdur. Bu gecikme "veri gönderme", sıralamadan gelen yükten çok daha büyüktür (0,75 sn ve 1,04 sn).

Yavaş alma işleminin sipariş tarafından birleştirildiğini unutmayın. Sırasız SQL durumunda, satırlar seçildikten sonra gönderilecektir. Sıralı olarak seçilen tüm satırlar seçildikten sonra ilk sonuç satırı gönderilmeden önce sıralanır.

+1

Pozisyonda bir dizin var, ancak çoğu satır özellikli olarak eklenmediğinden çoğu durumda bir konum olmayacak. Ben MYSQL tarafında sıralama atlamak için bir PHP sıralama uygulanmıştı, ama sıralama onu hızlandırdı beri ben hiçbir gelişme yok .. Eğer sıralanmamış PDO hızlandırabilirsem, o zaman işe yarayabileceğini düşünüyorum. Bunun için tavsiyen var mı? – Ripptor

0

Tablo tanımlarını (alanlar, alan türleri vb.) Kaydeder misiniz? masanın tags yılında tag basit endeksi

İlk tabloda search_all yılında date basit indeks eklersiniz ve

.

+0

Tablo tanımları eklendi. Search_all içinde bir tarih dizini vardır ve etiketler tablosu üçlü anahtardır (item_id, item_type, tag) – Ripptor

+0

@Ripptor: Bir indeks '(tag)' indeksten çok farklıdır (item_id, item_type, tag) –