SQL ประกาศหรือไม่


22

ฉันถามเพราะคำถามมากมายที่ฉันเห็นในจำนวน SQL ถึง: "นี่ช้าฉันจะเร่งความเร็วได้อย่างไร"? หรือแบบฝึกหัดที่ระบุว่า "ทำแบบนี้ไม่ใช่แบบนั้นเพราะมันเร็วกว่า"

สำหรับฉันแล้วดูเหมือนว่าส่วนใหญ่ของ SQL จะรู้วิธีการแสดงออกและการแสดงออกของความรู้ที่เลือกสไตล์การแสดงออกที่ดีขึ้น สิ่งนี้ไม่ได้เป็นรูปสี่เหลี่ยมจัตุรัสในแง่มุมหนึ่งของการเขียนโปรแกรมเชิงประกาศซึ่งเป็นการออกจากระบบเพื่อตัดสินใจว่าจะทำการคำนวณอย่างไรให้ดีที่สุดกับคุณเพียงแค่ระบุสิ่งที่การคำนวณควรสร้าง

ไม่ควรเครื่องยนต์ SQL ไม่สนใจเกี่ยวกับถ้าคุณใช้in, existsหรือjoinถ้ามันเป็นจริงที่เปิดเผยไม่ควรมันก็ให้คำตอบที่ถูกต้องในเวลาที่เหมาะสมถ้าเป็นไปได้ใด ๆ ของทั้งสามวิธี? ตัวอย่างล่าสุดนี้ได้รับแจ้งจากโพสต์ล่าสุดนี้ซึ่งเป็นประเภทที่ระบุไว้ในย่อหน้าเปิดของฉัน

ดัชนี

ฉันเดาตัวอย่างที่ง่ายที่สุดที่ฉันสามารถใช้เกี่ยวข้องกับการสร้างดัชนีสำหรับตาราง ชัยชนะที่นี่บน w3schools.comแม้พยายามอธิบายว่าเป็นสิ่งที่ผู้ใช้มองไม่เห็นซึ่งมีเหตุผลด้านประสิทธิภาพ คำอธิบายของพวกเขาดูเหมือนจะใส่ดัชนี SQL ในค่ายที่ไม่ประกาศและพวกเขาจะถูกเพิ่มด้วยมือเป็นประจำด้วยเหตุผลด้านประสิทธิภาพอย่างหมดจด

เป็นกรณีที่มี SQL DB ในอุดมคติที่เปิดเผยมากกว่าที่เหลือทั้งหมด แต่เพราะเป็นสิ่งที่ดีไม่ได้ยินหรือไม่


@ FrustratedWithFormsDesigner: ฉันรู้ว่ามันแปลว่าอะไร select whatever from sometable where FKValue in (select FKValue from sometable_2 where other_value = :param). มันควรจะเป็นที่น่ารำคาญเพื่อดูวิธีการย้ำว่ากับหรือexists join
Mason Wheeler

การใช้การใช้เหตุผลที่คล้ายกันฉันเดาว่านิพจน์ทั่วไปเป็นวิธีการแสดงออกที่ชัดเจนกว่าเนื่องจากฉันไม่ค่อยเห็นคำถามประสิทธิภาพที่ตอบโดย "คุณควรเขียนวิธีนี้เพื่อให้ได้ประสิทธิภาพที่ดีขึ้น" ฉันกำลังสมองของฉันอยู่และสามารถจำคำถามได้บ้างเกี่ยวกับการมองลบหรือการยืนยันล่วงหน้าใน regexp ช้าซึ่งคำตอบคือการเขียน regexp ใหม่ในวิธีที่ต่างกันในเวลาที่น้อยลง
Paddy3118

ประสิทธิภาพคือรายละเอียดการนำไปปฏิบัติ ประสิทธิภาพของการใช้งาน IN เกือบทุกอย่างสามารถเทียบเคียงหรือดีกว่า EXISTS และ JOIN ได้หากผู้พัฒนาตัวประมวลผลคิวรีรู้สึกว่ามีความสำคัญ
JustinC

1
@JustinC ดูเหมือนว่าจะเป็นมากกว่ารายละเอียดที่กำหนดความสำคัญของคำถาม SQL เชิงประสิทธิภาพและเคล็ดลับสำหรับภาษาที่คาดคะเนประกาศ?
Paddy3118

ไม่มีคำจำกัดความที่ชัดเจนของภาษาการเขียนโปรแกรมที่ประกาศดังนั้นจึงไม่มีความหมายที่จะพูดถึง บางภาษามีระดับสูงกว่าภาษาอื่น ๆ นั่นคือทั้งหมด
Gardenhead

คำตอบ:


21

SQL เป็นการประกาศตามหลักวิชา แต่คุณรู้ว่าสิ่งที่พวกเขาพูดเกี่ยวกับความแตกต่างระหว่างทฤษฎีและการปฏิบัติ ...

ที่เป็นแกนหลักแนวคิดของ "การเขียนโปรแกรมเชิงประกาศ" ไม่เคยมีประสิทธิภาพอย่างแท้จริงและน่าจะไม่เกิดขึ้นจนกว่าเราจะมีคอมไพเลอร์ที่ใช้ AI ซึ่งสามารถดูรหัสและตอบคำถาม "ความตั้งใจของรหัสนี้คืออะไร" อย่างชาญฉลาดในลักษณะเดียวกับที่คนที่เขียนมันจะ หัวใจสำคัญของทุกภาษาที่ประกาศคือกลุ่มของรหัสที่จำเป็นทั้งหมดซึ่งพยายามอย่างเมามันเพื่อแก้ปัญหานั้นโดยไม่ได้รับความช่วยเหลือจาก AI

บ่อยครั้งที่มันใช้งานได้ดีอย่างน่าประหลาดใจเพราะกรณีทั่วไปส่วนใหญ่เป็นกรณีทั่วไปซึ่งคนที่เขียนการใช้ภาษารู้และพบวิธีที่ดีในการจัดการ แต่คุณจะพบกับกรณีขอบที่ผู้ใช้ไม่ได้พิจารณาและคุณเห็นว่าประสิทธิภาพลดลงอย่างรวดเร็วเนื่องจากล่ามถูกบังคับให้ใช้รหัสมากขึ้นอย่างแท้จริงและจัดการในลักษณะที่มีประสิทธิภาพน้อยลง


3
ไม่เคยมีประสิทธิภาพอย่างแท้จริง? SQL, LINQ, Knockout.js, Prolog, ภาษา ELM คุณอาจต้องการตรวจสอบอีกครั้ง ฉันกำลังใช้เทคโนโลยีที่เปิดเผยส่วนใหญ่ในขณะนี้
brian

5
@ ไบรอัน: และทั้งหมดของพวกเขาเสื่อมโทรมค่อนข้างเร็วเมื่อคุณเกิดขึ้นในกรณีที่ไม่มีใครคิด ฉันคิดว่าฉันควรจะพูดว่า "ไม่เคยมีประสิทธิภาพอย่างแท้จริงในกรณีทั่วไป "
Mason Wheeler

คำตอบของคุณถูกตั้งค่าให้ลดระดับเมื่อเห็นว่ามันถูกเก็บไว้ในฐานข้อมูล SQL Server อย่างไร :) ฉันแทบจะไม่ได้รับความได้เปรียบจากกรณีใด ๆ ที่ไม่สามารถแก้ไขได้ภายในกรอบ ฉันเห็นว่าคุณมาจากไหน แต่คดีขอบไม่ได้ทำให้ฉันเจ็บปวดมากนักว่าประโยชน์และเหตุผลง่ายๆในการประมาณ 99% ของรหัสที่เปิดเผยคืออะไร มันเหมือนกับว่า Clojure หรือ F # ไม่ดีเพราะคุณต้องใช้ประเภทที่ไม่แน่นอนในการแก้ปัญหาของคุณ
brian

11
@ ไบรอัน: I rarely hit an edge case in any of them that couldn't be solved within the framework.ใช่นั่นคือจุดทั้งหมด: ต้องคิดหาวิธีการแก้ปัญหาภายในกรอบเพราะกรอบไม่ฉลาดพอที่จะแก้ปัญหาให้คุณในแบบที่คุณประกาศไว้ในตอนแรก
Mason Wheeler

สิ่งที่เกี่ยวกับเลือก ... สำหรับการปรับปรุง? ดูเหมือนว่าคำสั่งที่จำเป็น
Jesvin Jose

6

ฉันคิดเรื่องนี้เมื่อหลายวันก่อนหลังจากการปรับให้เหมาะสมของ SQL ฉันคิดว่าเราสามารถตกลงกันได้ว่า SQL เป็น "ภาษาที่ประกาศ" ในคำจำกัดความของ Wikipedia:

กระบวนทัศน์การเขียนโปรแกรมที่แสดงออกถึงตรรกะของการคำนวณโดยไม่ต้องอธิบายการไหลของการควบคุม

หากคุณคิดว่ามีกี่สิ่งที่ต้องทำหลังม่าน (ดูสถิติการตัดสินใจว่าดัชนีมีประโยชน์หรือไม่การเข้าร่วมซ้อนหรือรวมแฮช ฯลฯ เป็นต้น) เราต้องยอมรับว่าเราให้ระดับสูง ตรรกะและฐานข้อมูลดูแลตรรกะการไหลของการควบคุมระดับต่ำทั้งหมด

นอกจากนี้ในสถานการณ์นี้บางครั้งเครื่องมือเพิ่มประสิทธิภาพฐานข้อมูลต้องการ "คำแนะนำ" จากผู้ใช้เพื่อให้ได้ผลลัพธ์ที่ดีที่สุด

คำจำกัดความทั่วไปของภาษา "ที่เปิดเผย" คือ (ฉันไม่สามารถหาแหล่งข้อมูลที่มีสิทธิ์ได้):

กระบวนทัศน์การเขียนโปรแกรมที่แสดงออกถึงผลลัพธ์ที่ต้องการของการคำนวณโดยไม่ต้องอธิบายขั้นตอนเพื่อให้บรรลุผล (เช่นเดียวกับ "อธิบายสิ่งที่ไม่ใช่วิธี")

หากเรายอมรับคำจำกัดความนี้เราจะพบปัญหาที่อธิบายโดย OP

ปัญหาแรกคือ SQL ให้วิธีการเทียบเท่าหลายวิธีในการกำหนด "ผลลัพธ์เดียวกัน" อาจเป็นความชั่วร้ายที่จำเป็น: ยิ่งพลังการแสดงออกที่เราให้กับภาษามากเท่าไหร่ก็ยิ่งมีแนวโน้มที่จะมีวิธีที่แตกต่างกันในการแสดงออกในสิ่งเดียวกัน

ตัวอย่างเช่นฉันได้รับการขอให้หนึ่งครั้งเพื่อเพิ่มประสิทธิภาพการค้นหานี้:

 SELECT Distinct CT.cust_type,  ct.cust_type_description 
   from customer c 
              INNER JOIN 
              Customer_type CT on c.cust_type=ct.cust_type;

เนื่องจากประเภทมีน้อยกว่าลูกค้ามากและมีดัชนีในcust_typeตารางลูกค้าฉันจึงประสบความสำเร็จในการปรับปรุงอย่างมากโดยเขียนใหม่เป็น:

 SELECT CT.cust_type,  ct.cust_type_description 
   from Customer_type CT
  Where exists ( select 1 from customer c 
                  Where c.cust_type=ct.cust_type);

ในกรณีเฉพาะนี้เมื่อฉันถามผู้พัฒนาสิ่งที่เขาต้องการบรรลุเขาบอกฉันว่า "ฉันต้องการลูกค้าทุกประเภทที่ฉันมีลูกค้าอย่างน้อยหนึ่งราย" นั่นก็คือคำอธิบายเครื่องมือเพิ่มประสิทธิภาพสามารถอธิบายได้อย่างบังเอิญ

ดังนั้นหากฉันสามารถค้นหาข้อความค้นหาที่เทียบเท่าและมีประสิทธิภาพมากกว่าได้ทำไมเครื่องมือเพิ่มประสิทธิภาพไม่สามารถทำเช่นเดียวกันได้

การเดาที่ดีที่สุดของฉันคือมันมีสองเหตุผลหลัก

SQL แสดงตรรกะ:

เนื่องจาก SQL แสดงตรรกะระดับสูงเราจะต้องการเครื่องมือเพิ่มประสิทธิภาพเพื่อ "เอาชนะ" เราและตรรกะของเราหรือไม่ ฉันจะตะโกนอย่างกระตือรือร้นว่า "ใช่" ถ้าไม่ใช่ทุกครั้งที่ฉันต้องบังคับให้เครื่องมือเพิ่มประสิทธิภาพเลือกเส้นทางการดำเนินการที่มีประสิทธิภาพที่สุด ฉันคิดว่าความคิดอาจช่วยให้เครื่องมือเพิ่มประสิทธิภาพทำได้ดีที่สุด (แก้ไขตรรกะของเราด้วย) แต่ให้ "กลไกคำใบ้" เพื่อช่วยเหลือเมื่อมีอะไรบางอย่างบ้าคลั่ง (เหมือนมีล้อ + เบรกอยู่ใน รถอิสระ)

ทางเลือกมากขึ้น = เวลามากขึ้น

แม้แต่เครื่องมือเพิ่มประสิทธิภาพ RDBMS ที่ดีที่สุดยังไม่ทดสอบเส้นทางการประมวลผลที่เป็นไปได้ทั้งหมดเนื่องจากต้องรวดเร็วมาก: การเพิ่มประสิทธิภาพการสืบค้นจาก 100ms ถึง 10ms เป็นอย่างไรถ้าฉันต้องใช้ทุกครั้งที่เลือกเส้นทางที่ดีที่สุด 100ms และนั่นคือโปรแกรมเพิ่มประสิทธิภาพที่ใช้ "ตรรกะระดับสูง" ของเรา หากควรทดสอบแบบสอบถาม SQL ที่เทียบเท่าทั้งหมดด้วยเวลาที่เครื่องมือเพิ่มประสิทธิภาพอาจเพิ่มขึ้นหลายครั้ง

อีกตัวอย่างที่ดีของการเขียนแบบสอบถามที่ไม่มี RDBMS จริง ๆ แล้วสามารถทำได้คือ (จากโพสต์บล็อกที่น่าสนใจนี้ )

SELECT t1.id, t1.value, SUM(t2.value)
  FROM mytable t1
       JOIN mytable t2
         ON t2.id <= t1.id
 GROUP BY t1.id, t1.value;

เกินกว่าจะเขียนได้เช่นนี้ (จำเป็นต้องใช้ฟังก์ชั่นการวิเคราะห์)

 SELECT id, value, SUM(t1.value) OVER (ORDER BY id)
   FROM mytable

1
ตัวอย่างของการเขียนการเข้าร่วมที่มีอยู่ใหม่นั้นน่าสนใจ กฎข้อหนึ่งที่ฉันพยายามสร้างความประทับใจให้กับผู้พัฒนา SQL คือการใช้ DISTINCT นั้นเป็นกลิ่นของรหัสไม่ว่าจะเป็นแบบสอบถามหรือตัวแบบข้อมูลอาจผิดมากและควรหาแนวทางที่แตกต่างออกไป
David Aldridge
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.