- MySQL
ในการทำงานในแต่ละวัน คุณพบข้อผิดพลาดที่ค่อนข้างคล้ายกันเมื่อเขียนแบบสอบถาม
ในบทความนี้ ฉันอยากจะยกตัวอย่างวิธีที่จะไม่เขียนคำสั่ง
- เลือกช่องทั้งหมด
เลือก * จากตารางเมื่อเขียนแบบสอบถาม อย่าใช้การเลือกช่องทั้งหมด - "*" ระบุเฉพาะฟิลด์ที่คุณต้องการจริงๆ วิธีนี้จะช่วยลดปริมาณข้อมูลที่ดึงและส่ง นอกจากนี้อย่าลืมเกี่ยวกับการครอบคลุมดัชนีด้วย แม้ว่าคุณต้องการฟิลด์ทั้งหมดในตารางจริงๆ แต่ก็เป็นการดีกว่าที่จะแสดงรายการเหล่านั้น ประการแรกจะปรับปรุงความสามารถในการอ่านโค้ด เมื่อใช้เครื่องหมายดอกจัน จะเป็นไปไม่ได้ที่จะทราบว่าช่องใดอยู่ในตารางโดยไม่ดู ประการที่สอง เมื่อเวลาผ่านไป จำนวนคอลัมน์ในตารางของคุณอาจเปลี่ยนแปลง และหากวันนี้มีคอลัมน์ INT ห้าคอลัมน์ ฟิลด์ TEXT และ BLOB อาจถูกเพิ่มในหนึ่งเดือน ซึ่งจะทำให้การเลือกช้าลง
- คำขอเป็นรอบ
คุณต้องเข้าใจอย่างชัดเจนว่า SQL เป็นภาษาที่ใช้ในการตั้งค่า บางครั้งโปรแกรมเมอร์ที่คุ้นเคยกับการคิดในแง่ของภาษาขั้นตอนพบว่าเป็นการยากที่จะเปลี่ยนความคิดเป็นภาษาของเซต ซึ่งสามารถทำได้ค่อนข้างง่ายโดยใช้กฎง่ายๆ - "อย่าดำเนินการค้นหาในวง" ตัวอย่างวิธีการนี้สามารถทำได้:1. ตัวอย่าง
$news_ids = get_list("เลือก news_id จาก today_news ");
ในขณะที่($news_id = get_next($news_ids))
$news = get_row("เลือกหัวข้อ, เนื้อหาจากข่าว WHERE news_id = ". $news_id);กฎนั้นง่ายมาก - ยิ่งมีคำขอน้อยเท่าไรก็ยิ่งดี (แม้ว่าจะมีข้อยกเว้นเช่นเดียวกับกฎอื่นๆ ก็ตาม) อย่าลืมเกี่ยวกับโครงสร้าง IN() โค้ดด้านบนสามารถเขียนได้ในแบบสอบถามเดียว:
เลือกชื่อ เนื้อหา จาก today_news INNER JOIN ข่าว USING(news_id)2. ส่วนแทรก
$log = parse_log();
ในขณะที่($บันทึก = ถัดไป($log))
query("INSERT INTO บันทึกค่า SET = ". $log["value"]);!}การเชื่อมต่อและดำเนินการหนึ่งแบบสอบถามจะมีประสิทธิภาพมากกว่ามาก:
INSERT INTO บันทึก (ค่า) ค่า (...), (...)3. อัปเดต
บางครั้งคุณจำเป็นต้องอัปเดตหลายแถวในตารางเดียว หากค่าที่อัปเดตเหมือนกันทุกอย่างก็ง่าย:
อัพเดทข่าว SET title="test" WHERE id IN (1, 2, 3).!}หากค่าที่เปลี่ยนแปลงแตกต่างกันไปในแต่ละเรคคอร์ด สามารถทำได้โดยใช้แบบสอบถามต่อไปนี้:
อัพเดทข่าว ตลท
หัวเรื่อง = กรณี
เมื่อ news_id = 1 แล้ว "aa"
เมื่อ news_id = 2 แล้ว "bb" สิ้นสุด
ที่ news_id ใน (1, 2)การทดสอบของเราแสดงให้เห็นว่าคำขอดังกล่าวเร็วกว่าคำขอแยกกันหลายรายการถึง 2-3 เท่า
- ดำเนินการกับฟิลด์ที่มีการจัดทำดัชนี
เลือก user_id จากผู้ใช้ โดยที่ blogs_count * 2 = $valueแบบสอบถามนี้จะไม่ใช้ดัชนี แม้ว่าคอลัมน์ blogs_count จะถูกจัดทำดัชนีก็ตาม สำหรับดัชนีที่จะใช้ จะต้องไม่ทำการแปลงใดๆ บนฟิลด์ที่จัดทำดัชนีไว้ในแบบสอบถาม สำหรับคำขอดังกล่าว ให้ย้ายฟังก์ชันการแปลงไปยังส่วนอื่น:
เลือก user_id จากผู้ใช้ โดยที่ blogs_count = $value / 2;ตัวอย่างที่คล้ายกัน:
เลือก user_id จากผู้ใช้ WHERE TO_DAYS(CURRENT_DATE) - TO_DAYS(ลงทะเบียนแล้ว) = DATE_SUB(CURRENT_DATE, INTERVAL 10 DAY);
จะ. - กำลังดึงแถวเพื่อนับจำนวนเท่านั้น
$result = mysql_query("SELECT * FROM table", $link);
$num_rows = mysql_num_rows($ผลลัพธ์);
หากคุณต้องการเลือกจำนวนแถวที่ตรงตามเงื่อนไขที่กำหนด ให้ใช้แบบสอบถามตาราง SELECT COUNT(*) FROM แทนที่จะเลือกแถวทั้งหมดเพื่อนับจำนวนแถว - กำลังเรียกแถวพิเศษ
$result = mysql_query("SELECT * FROM table1", $link);
ในขณะที่($row = mysql_fetch_assoc($result) && $i< 20) {
…
}
หากคุณต้องการดึงข้อมูลเพียง n แถว ให้ใช้ LIMIT แทนการยกเลิก เส้นพิเศษในใบสมัคร - ใช้ ORDER BY RAND()
SELECT * จากตาราง ORDER BY RAND() จำกัด 1;หากตารางมีมากกว่า 4-5,000 แถว ORDER BY RAND() จะทำงานช้ามาก การเรียกใช้สองแบบสอบถามจะมีประสิทธิภาพมากกว่ามาก:
หากตารางมีคีย์หลัก auto_increation และไม่มีช่องว่าง:
$rnd = rand(1, query("SELECT MAX(id) FROM table");
$row = query("SELECT * FROM table WHERE id = ".$rnd);หรือ:
$cnt = query("SELECT COUNT(*) FROM table");
$row = query("SELECT * FROM table LIMIT ".$cnt.", 1");
อย่างไรก็ตาม ซึ่งอาจช้าได้หากมีแถวจำนวนมากในตาราง - การใช้งาน ปริมาณมากเข้าร่วม
เลือก
v.video_id
ก.ชื่อ
g.ประเภท
จาก
วิดีโอ AS v
เข้าร่วมทางซ้าย
link_actors_videos AS la ON la.video_id = v.video_id
เข้าร่วมทางซ้าย
นักแสดง AS a ON a.actor_id = la.actor_id
เข้าร่วมทางซ้าย
link_genre_video AS lg บน lg.video_id = v.video_id
เข้าร่วมทางซ้าย
ประเภท AS g ON g.genre_id = lg.genre_idต้องจำไว้ว่าเมื่อเชื่อมต่อตารางแบบหนึ่งต่อหลายแถวจำนวนแถวที่เลือกจะเพิ่มขึ้นตามแต่ละ JOIN ถัดไป ในกรณีเช่นนี้ การแยกแบบสอบถามดังกล่าวออกเป็นหลาย ๆ แถวจะเร็วกว่า
- ใช้ LIMIT
เลือก... จากตาราง จำกัด $start, $per_pageหลายๆ คนคิดว่าแบบสอบถามดังกล่าวจะส่งกลับ $per_page ของระเบียน (ปกติคือ 10-20) ดังนั้นจึงจะทำงานได้อย่างรวดเร็ว มันจะทำงานได้อย่างรวดเร็วสำหรับสองสามหน้าแรก แต่ถ้าจำนวนบันทึกมีขนาดใหญ่ และคุณต้องดำเนินการ SELECT... FROM table LIMIT 1000000, 1000020 แบบสอบถาม จากนั้นในการดำเนินการค้นหาดังกล่าว MySQL จะเลือก 1000020 ระเบียนก่อน ทิ้งล้านแรกแล้วส่งคืน 20 สิ่งนี้ อาจจะไม่เร็วเลย ไม่มีวิธีแก้ไขปัญหาเล็กน้อย หลายๆ เว็บจำกัดจำนวนเพจที่มีอยู่ให้อยู่ในจำนวนที่เหมาะสม คุณยังสามารถเพิ่มความเร็วการสืบค้นดังกล่าวได้โดยใช้ดัชนีที่ครอบคลุมหรือ โซลูชันของบุคคลที่สาม(เช่น สฟิงซ์)
- ไม่ได้ใช้ ON DUPLICATE KEY UPDATE
$row = query("SELECT * FROM table WHERE id=1");ถ้า($แถว)
แบบสอบถาม ("อัปเดตตาราง SET คอลัมน์ = คอลัมน์ + 1 WHERE id = 1")
อื่น
query("INSERT INTO table SET column = 1, id=1");โครงสร้างที่คล้ายกันสามารถแทนที่ได้ด้วยแบบสอบถามเดียว โดยมีเงื่อนไขว่าต้องมีคีย์หลักหรือคีย์เฉพาะสำหรับฟิลด์ id:
แทรกลงในคอลัมน์ SET ของตาราง = 1, id = 1 บนคอลัมน์การอัปเดตคีย์ซ้ำ = คอลัมน์ + 1
ฉันได้เขียนเกี่ยวกับการสืบค้น SQL ที่หลากหลายแล้ว แต่ถึงเวลาที่จะพูดถึงสิ่งที่ซับซ้อนมากขึ้น เช่น การสืบค้น SQL เพื่อเลือกบันทึกจากหลายตาราง
เมื่อคุณและฉันเลือกจากตารางเดียว ทุกอย่างก็ง่ายมาก:
เลือก name_of_required_fields จาก table_name WHERE select_condition
ทุกอย่างเรียบง่ายและไม่สำคัญ แต่เมื่อสุ่มตัวอย่างจากหลาย ๆ ตารางพร้อมกันมันจะค่อนข้างซับซ้อนมากขึ้น ปัญหาประการหนึ่งคือการจับคู่ชื่อฟิลด์ ตัวอย่างเช่น ทุกตารางมีช่องรหัส
ลองดูที่แบบสอบถามนี้:
เลือก * จาก table_1, table_2 โดยที่ table_1.id > table_2.user_id
หลายๆ คนที่ไม่ได้จัดการกับข้อความค้นหาดังกล่าวจะคิดว่าทุกอย่างง่ายมาก โดยคิดว่ามีเพียงชื่อตารางเท่านั้นที่ถูกเพิ่มไว้หน้าชื่อเขตข้อมูล อันที่จริงแล้ว วิธีนี้จะช่วยหลีกเลี่ยงความขัดแย้งระหว่างชื่อฟิลด์ที่เหมือนกัน อย่างไรก็ตามความยากไม่ได้อยู่ที่สิ่งนี้ แต่อยู่ที่อัลกอริธึมของการสืบค้น SQL ดังกล่าว
อัลกอริธึมการทำงานมีดังนี้: บันทึกแรกนำมาจาก table_1 รหัสของบันทึกนี้นำมาจาก table_1 จากนั้นตาราง table_2 ก็ดูสมบูรณ์ และบันทึกทั้งหมดจะถูกเพิ่มโดยที่ค่าของช่อง user_id น้อยกว่า id ของบันทึกที่เลือกใน table_1 ดังนั้น หลังจากการวนซ้ำครั้งแรก อาจมีบันทึกผลลัพธ์ตั้งแต่ 0 ถึงจำนวนอนันต์ ในการวนซ้ำครั้งถัดไป จะมีการใช้บันทึกถัดไปของตาราง table_1 ระบบจะสแกนตาราง table_2 ทั้งหมดอีกครั้ง และเงื่อนไขการเลือก table_1.id > table_2.user_id จะถูกทริกเกอร์อีกครั้ง เรกคอร์ดทั้งหมดที่ตรงตามเงื่อนไขนี้จะถูกเพิ่มลงในผลลัพธ์ ผลลัพธ์อาจมีบันทึกจำนวนมาก ซึ่งใหญ่กว่าขนาดรวมของทั้งสองตารางหลายเท่า
หากคุณเข้าใจวิธีการทำงานหลังจากครั้งแรกก็ถือว่าดี แต่ถ้าไม่ก็ให้อ่านจนกว่าคุณจะเข้าใจอย่างถ่องแท้ ถ้าเข้าใจเรื่องนี้ก็จะง่ายขึ้น
แบบสอบถาม SQL ก่อนหน้านี้ไม่ค่อยได้ใช้ มีไว้เพื่ออธิบายอัลกอริธึมการสุ่มตัวอย่างแบบหลายตาราง ตอนนี้เรามาดูแบบสอบถาม SQL แบบย่อเพิ่มเติม สมมติว่าเรามีสองตาราง: กับผลิตภัณฑ์ (มีช่อง Owner_id ซึ่งรับผิดชอบ ID ของเจ้าของผลิตภัณฑ์) และกับผู้ใช้ (มีช่อง ID) เราต้องการรับบันทึกทั้งหมดในแบบสอบถาม SQL เดียว และแต่ละรายการมีข้อมูลเกี่ยวกับผู้ใช้และผลิตภัณฑ์เดียวของเขา รายการถัดไปมีข้อมูลเกี่ยวกับผู้ใช้รายเดียวกันและผลิตภัณฑ์ถัดไปของเขา เมื่อผลิตภัณฑ์ของผู้ใช้รายนี้หมด ให้ไปยังผู้ใช้รายถัดไป ดังนั้นเราจึงต้องรวมสองตารางและรับผลลัพธ์ซึ่งแต่ละบันทึกประกอบด้วยข้อมูลเกี่ยวกับผู้ใช้และผลิตภัณฑ์หนึ่งรายการของเขา
แบบสอบถามที่คล้ายกันจะแทนที่แบบสอบถาม SQL 2 รายการ: เพื่อเลือกแยกจากตารางที่มีสินค้าและจากตารางที่มีผู้ใช้ นอกจากนี้ คำขอดังกล่าวจะจับคู่ผู้ใช้และผลิตภัณฑ์ของเขาทันที
คำขอนั้นง่ายมาก (หากคุณเข้าใจคำขอก่อนหน้า):
SELECT * จากผู้ใช้ ผลิตภัณฑ์ WHERE users.id = products.owner_id
อัลกอริธึมที่นี่ง่ายอยู่แล้ว: บันทึกแรกนำมาจากตารางผู้ใช้ ถัดไป รหัสจะถูกนำไปใช้และบันทึกทั้งหมดจากตารางผลิตภัณฑ์จะถูกวิเคราะห์ โดยเพิ่มผลลัพธ์ที่เจ้าของ _id เท่ากับรหัสจากตารางผู้ใช้ ดังนั้นในการวนซ้ำครั้งแรก สินค้าทั้งหมดจากผู้ใช้รายแรกจะถูกรวบรวม ในการวนซ้ำครั้งที่สอง ผลิตภัณฑ์ทั้งหมดจากผู้ใช้คนที่สองจะถูกรวบรวม และอื่นๆ
อย่างที่คุณเห็น การสืบค้น SQL สำหรับการเลือกจากหลายตารางนั้นไม่ใช่วิธีที่ง่ายที่สุด แต่ประโยชน์ที่ได้รับอาจมีมหาศาล ดังนั้นการรู้และสามารถใช้การสืบค้นดังกล่าวจึงเป็นที่ต้องการอย่างมาก
ในบทเรียนที่แล้วเราพบความไม่สะดวกประการหนึ่ง เมื่อเราต้องการทราบว่าใครเป็นผู้สร้างหัวข้อ “จักรยาน” เราก็ได้ร้องขอที่เกี่ยวข้อง:
เราได้รับตัวระบุของเขาแทนชื่อผู้เขียน สิ่งนี้เป็นสิ่งที่เข้าใจได้เนื่องจากเราทำการสืบค้นในตารางหนึ่ง - หัวข้อและชื่อของผู้เขียนหัวข้อจะถูกเก็บไว้ในตารางอื่น - ผู้ใช้ ดังนั้นเมื่อพบตัวระบุของผู้เขียนหัวข้อแล้ว เราจำเป็นต้องทำการสืบค้นอีกครั้ง - ไปที่ตาราง Users เพื่อค้นหาชื่อของเขา:
SQL ให้ความสามารถในการรวมแบบสอบถามดังกล่าวเป็นหนึ่งเดียวโดยการเปลี่ยนหนึ่งในนั้นให้เป็นแบบสอบถามย่อย (แบบสอบถามแบบซ้อน) ดังนั้น หากต้องการทราบว่าใครเป็นผู้สร้างหัวข้อ "จักรยาน" เราจะทำการสืบค้นต่อไปนี้:
นั่นคืออยู่หลังคีย์เวิร์ด ที่ไหนเราเขียนคำขออื่นในเงื่อนไข MySQL ประมวลผลแบบสอบถามย่อยก่อน ส่งกลับ id_author=2 และค่านี้จะถูกส่งผ่านไปยังส่วนคำสั่ง ที่ไหนคำขอภายนอก
แบบสอบถามเดียวสามารถมีได้หลายแบบสอบถามย่อย ไวยากรณ์สำหรับแบบสอบถามดังกล่าวมีดังนี้: โปรดทราบว่าแบบสอบถามย่อยสามารถเลือกได้เพียงคอลัมน์เดียว โดยค่าที่จะส่งคืนไปยังแบบสอบถามภายนอก การพยายามเลือกหลายคอลัมน์จะส่งผลให้เกิดข้อผิดพลาด
เพื่อรวมสิ่งนี้เข้าด้วยกัน เราขออีกครั้งและค้นหาข้อความที่ผู้เขียนหัวข้อ "จักรยาน" ทิ้งไว้ในฟอรัม:
ตอนนี้เรามาทำให้งานซับซ้อนขึ้นค้นหาว่าหัวข้อใดที่ผู้เขียนหัวข้อ "จักรยาน" ทิ้งข้อความไว้:
เรามาดูกันว่ามันทำงานอย่างไร
- MySQL จะดำเนินการค้นหาที่ลึกที่สุดก่อน:
- ผลลัพธ์ที่ได้ (id_author=2) จะถูกส่งไปยังคำขอภายนอก ซึ่งจะอยู่ในรูปแบบ:
- ผลลัพธ์ที่ได้ (id_topic:4,1) จะถูกส่งไปยังคำขอภายนอก ซึ่งจะอยู่ในรูปแบบ:
- และจะให้ผลลัพธ์สุดท้าย (topic_name: about fishing, about fishing) เหล่านั้น. ผู้เขียนหัวข้อ "จักรยาน" ฝากข้อความไว้ในหัวข้อ "เกี่ยวกับการตกปลา" ที่สร้างโดย Sergei (id=1) และในหัวข้อ "เกี่ยวกับการตกปลา" ที่สร้างโดย Sveta (id=4)
- ไม่แนะนำให้สร้างแบบสอบถามที่มีระดับการซ้อนมากกว่าสาม สิ่งนี้นำไปสู่เวลาดำเนินการที่เพิ่มขึ้นและความยากลำบากในการทำความเข้าใจโค้ด
- ไวยากรณ์ที่กำหนดสำหรับการสืบค้นแบบซ้อนอาจเป็นแบบที่พบบ่อยที่สุด แต่ไม่ใช่แบบเดียว เช่น แทนที่จะถาม
เขียน
เหล่านั้น. เราสามารถใช้โอเปอเรเตอร์ใดก็ได้ที่ใช้ร่วมกับ คำหลักที่ไหน (เราศึกษาพวกเขาในบทเรียนที่แล้ว)
ในบทความสั้นๆ นี้ เราจะพูดถึงฐานข้อมูลโดยเฉพาะ MySQL การสุ่มตัวอย่างและการนับจำนวน เมื่อทำงานกับฐานข้อมูล คุณมักจะต้องนับปริมาณ บรรทัด COUNT() มีหรือไม่มีเงื่อนไขที่แน่นอน การดำเนินการนี้ทำได้ง่ายมากตามคำขอต่อไปนี้
ดูโค้ด MySQL
แบบสอบถามจะส่งคืนค่าพร้อมจำนวนแถวในตาราง
นับแบบมีเงื่อนไข
ดูโค้ด MySQL
แบบสอบถามจะส่งกลับค่าด้วยจำนวนแถวในตารางที่พอใจ เงื่อนไขนี้: วาร์ = 1
หากต้องการรับค่าจำนวนแถวหลายค่าที่มีเงื่อนไขต่างกัน คุณสามารถเรียกใช้คิวรีหลายรายการได้ทีละรายการ เป็นต้น
ดูโค้ด MySQL
แต่ในบางกรณี วิธีการนี้ใช้ไม่ได้จริงหรือเหมาะสมที่สุด ดังนั้นจึงมีความเกี่ยวข้องในการจัดระเบียบแบบสอบถามที่มีแบบสอบถามย่อยหลายรายการเพื่อให้ได้ผลลัพธ์หลายรายการพร้อมกันในแบบสอบถามเดียว ตัวอย่างเช่น
ดูโค้ด MySQL
ดังนั้น โดยการดำเนินการเพียงหนึ่งแบบสอบถามไปยังฐานข้อมูล เราจะได้ผลลัพธ์ที่มีการนับจำนวนแถวสำหรับเงื่อนไขต่างๆ ที่มีค่าการนับหลายค่า เช่น
ดูโค้ดข้อความ
c1|c2|c3 -------- 1 |5 |8 |
ข้อเสียของการใช้แบบสอบถามย่อยเมื่อเปรียบเทียบกับแบบสอบถามแยกกันหลายๆ แบบสอบถาม คือความเร็วของการดำเนินการและภาระงานในฐานข้อมูล
ตัวอย่างต่อไปนี้ของแบบสอบถามที่มี COUNT หลายรายการในหนึ่งเดียว แบบสอบถาม MySQLมีโครงสร้างแตกต่างออกไปเล็กน้อย โดยใช้โครงสร้าง IF(condition, value1, value2) รวมถึงการบวก SUM() ช่วยให้คุณสามารถเลือกข้อมูลตามเกณฑ์ที่กำหนดภายในแบบสอบถามเดียว จากนั้นจึงสรุปและแสดงค่าหลายค่าตามผลลัพธ์
ดูโค้ด MySQL
ดังที่เห็นได้จากคำขอ มันถูกสร้างขึ้นค่อนข้างรวบรัด แต่ความเร็วในการดำเนินการก็ไม่เป็นที่พอใจเช่นกัน ของคำขอนี้จะมีอันต่อไป
ดูโค้ดข้อความ
รวม|c1|c2|c3 -------------- 14 |1 |5 |8 |
ต่อไป ฉันจะให้สถิติเปรียบเทียบความเร็วในการดำเนินการของตัวเลือกการสืบค้นสามตัวเลือกสำหรับการเลือก COUNT() หลายรายการ เพื่อทดสอบความเร็วของการดำเนินการค้นหา ได้มีการดำเนินการค้นหา 1,000 รายการในแต่ละประเภท โดยมีตารางที่มีบันทึกมากกว่าสามพันรายการ นอกจากนี้ ในแต่ละครั้งที่คำขอมี SQL_NO_CACHE เพื่อปิดใช้งานการแคชผลลัพธ์โดยฐานข้อมูล
ความเร็วในการดำเนินการ
สามคำขอแยกกัน: 0.9 วินาที
หนึ่งแบบสอบถามที่มีแบบสอบถามย่อย: 0.95 วินาที
หนึ่งคำขอที่มีการสร้าง IF และ SUM: 1.5 วินาที
บทสรุป. ดังนั้นเราจึงมีตัวเลือกมากมายสำหรับการสร้างแบบสอบถามไปยังฐานข้อมูล ข้อมูลมายเอสคิวแอลเมื่อใช้หลาย COUNT() ตัวเลือกแรกที่มีการสืบค้นแยกกันนั้นไม่สะดวกนัก แต่จะให้ผลลัพธ์ความเร็วที่ดีที่สุด ตัวเลือกที่สองที่มีแบบสอบถามย่อยนั้นค่อนข้างสะดวกกว่า แต่ความเร็วในการดำเนินการนั้นต่ำกว่าเล็กน้อย และในที่สุด เวอร์ชันย่อที่สามของคิวรีที่มีโครงสร้าง IF และ SUM ซึ่งดูสะดวกที่สุดก็มีมากที่สุด ความเร็วต่ำประสิทธิภาพซึ่งต่ำกว่าสองตัวเลือกแรกเกือบสองเท่า ดังนั้นเมื่อปรับการทำงานของฐานข้อมูลให้เหมาะสม ฉันขอแนะนำให้ใช้เวอร์ชันที่สองของแบบสอบถามที่มีแบบสอบถามย่อยด้วย COUNT() ประการแรกความเร็วในการดำเนินการใกล้เคียงกับผลลัพธ์ที่เร็วที่สุดและประการที่สอง องค์กรดังกล่าวภายในแบบสอบถามเดียวนั้นค่อนข้างสะดวก .