เหตุใด SELECT จึงเป็นขนาดเร็วกว่า SELECT foo


28

พิจารณาตารางค่าและแฮชเช่น:

+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| val        | char(9)  | NO   |     | NULL    |                |
| val_hashed | char(50) | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

แบบสอบถามต่อไปนี้เสร็จสิ้นใน 0.00 วินาที:

SELECT * FROM hashes ORDER BY 1 DESC LIMIT 1;

อย่างไรก็ตามการสืบค้นนี้ใช้เวลา 3 นาที 17 วินาที:

SELECT val FROM hashes ORDER BY 1 DESC LIMIT 1;

Sorting resultผมเห็นว่าในขณะที่แบบสอบถามจะทำงานแสดงรายการกระบวนการว่ามันเป็นสถานะ สถานการณ์สามารถทำซ้ำได้อย่างสมบูรณ์ โปรดทราบว่ามีกระบวนการอื่นที่ดำเนินการINSERTการดำเนินการบนตารางอย่างต่อเนื่อง

เหตุใดข้อความค้นหาที่เจาะจงมากขึ้นจึงใช้เวลานานกว่า*แบบสอบถาม ฉันเชื่อเสมอว่า*ควรหลีกเลี่ยงการค้นหาโดยเฉพาะด้วยเหตุผลด้านประสิทธิภาพ


7
คำสั่งแรกส่วนใหญ่อาจใช้ดัชนีคีย์หลักในidการค้นหาแถวแรก รายการที่สองต้องเรียงลำดับผลลัพธ์ที่สมบูรณ์ในvalคอลัมน์(ยกเลิกการทำดัชนี)
a_horse_with_no_name

8
ORDER BY NUMBERไวยากรณ์ค่อนข้างผิดพลาดง่าย
usr

2
การเพิ่มความคิดเห็นล่าสุดของคุณSELECT *รวมกับดัชนีคอลัมน์ในORDER BYนั้นทำให้สับสนคอลัมน์ที่จะถูกจัดเรียง - อีกเหตุผลหนึ่งที่จะหลีกเลี่ยง*s ...
lc

@lc. คุณหมายถึงอะไร
Pacerier

@Pierier ฉันหมายถึง*ไม่ชัดเจน ดังนั้นการพูดว่า "ให้คอลัมน์ทั้งหมดกับฉันและจัดเรียงตามลำดับที่สาม" เป็นเรื่องเกี่ยวกับการกำหนดว่า "ไปที่ซุปเปอร์มาร์เก็ตแล้วบอกฉันว่าคุณผ่านสัญญาณไฟจราจรกี่ครั้ง"
lc

คำตอบ:


33

วลีนี้ORDER BY 1อ้างถึงคอลัมน์ต่าง ๆ ; ในครั้งแรกมันจะเป็นในครั้งที่สองid valเนื่องจากidเป็นกุญแจสำคัญที่จะได้รับการจัดทำดัชนีและorder byจะเป็นจำนวนเล็กน้อยของการทำงาน ต้องการorder by valแต่ระบบจะต้องดึงทุกแถวเรียงลำดับตารางโดยสมบูรณ์valแล้วเลือกเพียงหนึ่งแถวเหล่านั้น

เปลี่ยนทั้งคำถามorder by idและฉันคิดว่าเวลาดำเนินการของคุณจะเกือบจะเหมือนกัน


3
บางครั้งคำถามที่ยากที่สุดก็คือคำถามที่จ้องมองเรา ขอบคุณไมเคิล!
dotancohen

7

ความแตกต่างของประสิทธิภาพในการสืบค้นของคุณนั้นถูกอธิบายไว้อย่างดีโดย MG ฉันจะพูดถึงสิ่งนี้:

ฉันเชื่อเสมอว่า * ควรหลีกเลี่ยงการค้นหาโดยเฉพาะเพื่อเหตุผลด้านประสิทธิภาพ

select *ไม่มีการลงโทษโดยเฉพาะอย่างยิ่งมันเป็นปัญหาเมื่อนำไปใช้ในทางที่ผิด ในการสืบค้นแบบตารางเดี่ยวมันใช้งานได้ดี ตอนนี้เข้าร่วมตารางนั้นกับอีก 20 คอลัมน์และต่อมาเพิ่มเข้าร่วม 5 ตารางอื่น ๆ ที่มีหลายคอลัมน์ ตอนนี้มันเป็นปัญหา ดังนั้นคนที่สอนวงดนตรีวงกว้าง "ไม่เคยทำ X" โดยไม่ต้องอธิบายว่าทำไม


3
SELECT *อาจเป็นปัญหาสำหรับการสืบค้นในตารางเดียว ตัวอย่างเช่นSELECT * FROM hashes ORDER BY val;อาจทำการสแกนแบบเต็มตารางจากนั้นเรียงลำดับในขณะที่SELECT val FROM hashes ORDER BY val;จะทำการสแกนดัชนีแบบเต็มเท่านั้นและไม่มีการเรียงลำดับ (สมมติว่ามีดัชนีอยู่บน val) ดังนั้นจึงไม่เจ็บที่จะเลือกเฉพาะผลลัพธ์ที่เราต้องการ
ypercubeᵀᴹ

ฉันคิดว่าคุณเคยเห็นสิ่งนี้? sqlblog.com/blogs/aaron_bertrand/archive/2009/10/10/…
Max Vernon

@ypercube สิ่งนั้นเกิดขึ้นแม้ว่าเราselect(*)จะใช้เป็นตัวเลือกย่อยเท่านั้นหรือไม่ เนื่องจากเป็นตัวเลือกแบบฝังตัว MySQL จะไม่ฉลาดพอที่จะเข้าใจคอลัมน์จริงที่ต้องเลือกใช่หรือไม่
Pacerier

@Pacerier mysql optimizer มีระดับ "smartness" ที่แตกต่างกันขึ้นอยู่กับรุ่นที่คุณใช้ ในความเป็นคนช่างมันเป็นคนค่อนข้างงี่เง่าเกี่ยวกับคำถามย่อยที่ซ้อนกันดังนั้นสิ่งใดก็ตามที่คุณสามารถทำได้เพื่อช่วยเขามันก็ดี
ypercubeᵀᴹ

@percube อาถ้าเพียง แต่ฉลาดเท่า pgsql
Pacerier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.