มีความแตกต่างระหว่าง GROUP BY และ DISTINCT หรือไม่


310

ฉันเรียนรู้บางอย่างเกี่ยวกับ SQL ในวันอื่น ๆ :

SELECT c FROM myTbl GROUP BY C

มีผลลัพธ์เช่นเดียวกับ:

SELECT DISTINCT C FROM myTbl

สิ่งที่ฉันอยากรู้มีอะไรแตกต่างกันในวิธีที่โปรแกรมเอ็นจิน SQL ประมวลผลคำสั่งหรือสิ่งนั้นเป็นสิ่งเดียวกันจริง ๆ หรือไม่?

ฉันชอบไวยากรณ์ที่แตกต่างโดยส่วนตัว แต่ฉันแน่ใจว่ามันเป็นนิสัยมากกว่าสิ่งอื่นใด

แก้ไข: นี่ไม่ใช่คำถามเกี่ยวกับมวลรวม การใช้GROUP BYฟังก์ชั่นรวมกับเป็นที่เข้าใจกัน


11
นี่ไม่ใช่คำถามเกี่ยวกับมวลรวมมันเป็นกลุ่มตามการทำงานเช่นเดียวกับที่แตกต่างกันเมื่อไม่มีฟังก์ชั่นรวมอยู่
Brettski

2
คุณสามารถทำSELECT c FROM myTbl UNION SELECT c FROM myTblและรับผลลัพธ์เดียวกันได้ ... แต่ทำไมสิ่งที่ซับซ้อนเมื่อเลือก DISTINCT นั้นง่ายมาก
jarlh

'ลำดับของการดำเนินการทางตรรกะ' ของGROUP BYนั้นเร็วกว่า 'SELECT' และDISTINCTตามด้วยการเลือก
Used_By_Already

ความแตกต่างเล็กน้อยอย่างหนึ่งที่ฉันไม่ได้เห็นกล่าวถึงคือDISTINCTผลลัพธ์ในการเลือกฟิลด์ - นั่นคือค่าจะปรากฏในชุดผลลัพธ์ GROUP BYสามารถลบรายการที่ซ้ำกันได้อย่างมีประสิทธิภาพโดยไม่ต้องเลือกฟิลด์จริง ในกรณีส่วนใหญ่นี้ไม่เกี่ยวข้อง แต่อาจเป็นสิ่งที่คุณต้องการในคนอื่น ๆ หากคุณใช้GROUP BYแทนDISTINCTความคิดเห็นที่อธิบายในรหัสอาจจะรับประกัน
rinogo

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

คำตอบ:


246

การตอบสนองของMusiGenesisนั้นเหมาะสมกับคำถามของคุณตามที่ระบุไว้ SQL Server นั้นฉลาดพอที่จะรู้ว่าถ้าคุณใช้ "Group By" และไม่ใช้ฟังก์ชั่นรวมใด ๆ แล้วสิ่งที่คุณหมายถึงคือ "Distinct" - และดังนั้นจึงสร้างแผนการดำเนินการราวกับว่าคุณใช้เพียงแค่ "Distinct ."

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

ค้อนสามารถทำงานเพื่อขับสกรูในบางครั้ง แต่ถ้าคุณมีไขควงมีประโยชน์ทำไมต้องรำคาญ?

(สำหรับวัตถุประสงค์ของการเปรียบเทียบนี้Hammer : Screwdriver :: GroupBy : Distinctและscrew => get list of unique values in a table column)


ฉันอยู่ในข้อตกลงที่สมบูรณ์กับคุณ Skeolan ฉันค่อนข้างประหลาดใจเมื่อฉันได้พบฟังก์ชั่นนี้ ไม่ใช่สิ่งที่ฉันวางแผนที่จะใช้ แต่มีหลายสิ่งที่ทำในสถานที่ใหม่นี้ที่ฉันกำลังทำงานอยู่
Brettski

อย่างน้อยใน Oracle 12 มีกรณีที่ DISTINCT รับค่าที่แตกต่างโดย UNION และ GROUP BY ทำงานแตกต่างกัน ฉันเพิ่งมีกรณีก่อนหน้านี้วันนี้ที่ DISTINCT และแตกต่างกันโดย UNION ทำให้เกิดข้อผิดพลาดของ oracle แต่ GROUP BY ทำงาน ฉันเลือกเพียง 1 คอลัมน์จากมุมมองและไม่ได้ใช้การรวมใด ๆ ฉันยังคงงงว่าทำไมมันถึงต้องการ แต่มันยืนยันว่ามีความแตกต่างในการทำงาน ดังที่คนอื่น ๆ ชี้ให้เห็นมันยังช่วยให้คุณแบ่งกลุ่มคอลัมน์ตามที่ไม่ได้อยู่ในตัวเลือกแม้ว่าจะไม่ค่อยจำเป็นโดยไม่ต้องรวม
ZeroK

1
เมื่อพูดถึง SQL คุณจะต้องมีทั้งไขควงและค้อนเสมอ ทำไมต้องใช้ค้อนขับในสกรู
jarlh

เพื่อให้ชัดเจนเกี่ยวกับการเปรียบเทียบคุณ - ค้อนของคุณ == GroupBy และไขควง == แตกต่างกันในกรณีนี้หรือไม่?
HopeKing

ว้าวคำถามสิบปีนี้ยังมีขา! "Distinct" คือไขควงหาก "รายการค่าที่ไม่ซ้ำ" คือสกรู ฉันจะอัปเดตคำตอบเพื่อให้การเปรียบเทียบชัดเจนขึ้น
Skeolan

136

GROUP BYช่วยให้คุณสามารถใช้ฟังก์ชันการรวมเช่นAVG, MAX, MIN, และSUM COUNTในทางกลับกันDISTINCTเพียงแค่ลบรายการที่ซ้ำกัน

ตัวอย่างเช่นหากคุณมีบันทึกการซื้อจำนวนมากและคุณต้องการทราบว่าแต่ละแผนกใช้จ่ายไปเท่าไรคุณอาจทำสิ่งต่อไปนี้

SELECT department, SUM(amount) FROM purchases GROUP BY department

สิ่งนี้จะให้คุณหนึ่งแถวต่อแผนกซึ่งมีชื่อแผนกและผลรวมของamountค่าทั้งหมดในแถวทั้งหมดสำหรับแผนกนั้น


2
การใช้ GROUP BY ฉันเข้าใจคำถามนี้ตั้งอยู่บนพื้นฐานของข้อเท็จจริงที่ว่ามันจะส่งคืนชุดข้อมูลที่แตกต่างเมื่อไม่มีฟังก์ชั่นรวม
Brettski

2
เนื่องจาก GROUP BY ทำหน้าที่ DISTINCT โดยปริยายมากกว่าค่าของคอลัมน์ที่คุณจัดกลุ่มตาม (ขออภัยสำหรับเสียงขรม)
Joe Pineda

เป็นไปไม่ได้ที่จะใช้DISTINCT+ ฟังก์ชั่นรวมหรือไม่? เช่นนี้:select distinct department, SUM(amount) from ...
Shafizadeh

@Sadad คุณสามารถทำได้ใช่ แต่คุณยังต้องมี GROUP BY ดังนั้น DISTINCT จะไม่ทำอะไรให้คุณเลย
ZeroK

44

ไม่มีความแตกต่าง (ใน SQL Server เป็นอย่างน้อย) แบบสอบถามทั้งสองใช้แผนการดำเนินการเดียวกัน

http://sqlmag.com/database-performance-tuning/distinct-vs-group

อาจจะมี เป็นความแตกต่างถ้ามีคำสั่งย่อยที่เกี่ยวข้อง:

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/

ไม่มีความแตกต่าง (สไตล์ Oracle):

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:32961403234212


40

ความแตกต่างจากมุมมองการทำงานของการลบแบบซ้ำซ้อนคืออะไร

นอกเหนือจากความเป็นจริงที่แตกต่างDISTINCT, GROUP BYช่วยให้การรวมข้อมูลต่อกลุ่ม (ซึ่งได้รับการกล่าวถึงโดยคำตอบอื่น ๆ อีกมากมาย) ความแตกต่างที่สำคัญที่สุดในความคิดของฉันคือความจริงที่ว่าทั้งสองดำเนินการ "เกิดขึ้น" ที่สองขั้นตอนที่แตกต่างกันมากในลำดับที่เป็นตรรกะ ของการดำเนินงานที่มีการดำเนินการในSELECTคำสั่ง

นี่คือการดำเนินการที่สำคัญที่สุด:

  • FROM(รวมทั้งJOIN, APPLYฯลฯ )
  • WHERE
  • GROUP BY (สามารถลบรายการซ้ำได้)
  • รวมตัว
  • HAVING
  • ฟังก์ชั่นหน้าต่าง
  • SELECT
  • DISTINCT (สามารถลบรายการซ้ำได้)
  • UNION, INTERSECT, EXCEPT (สามารถลบข้อมูลที่ซ้ำกัน)
  • ORDER BY
  • OFFSET
  • LIMIT

อย่างที่คุณเห็นลำดับลอจิคัลของการดำเนินการแต่ละอย่างมีผลต่อสิ่งที่สามารถทำได้ โดยเฉพาะอย่างยิ่งความจริงที่ว่าการGROUP BYดำเนินการ"เกิดขึ้นก่อน"การSELECTดำเนินการ (ประมาณการ) หมายความว่า:

  1. มันไม่ได้ขึ้นอยู่กับการฉาย (ซึ่งอาจเป็นประโยชน์)
  2. ไม่สามารถใช้ค่าใด ๆ จากการฉายภาพ (ซึ่งอาจเป็นข้อเสีย)

1. มันไม่ได้ขึ้นอยู่กับการฉาย

ตัวอย่างที่ไม่ได้ขึ้นอยู่กับการฉายมีประโยชน์คือถ้าคุณต้องการคำนวณฟังก์ชั่นหน้าต่างในค่าที่แตกต่าง:

SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
GROUP BY rating

เมื่อทำงานกับฐานข้อมูล Sakilaผลตอบแทนนี้:

rating   rn
-----------
G        1
NC-17    2
PG       3
PG-13    4
R        5

สิ่งเดียวกันนี้ไม่สามารถทำได้DISTINCTอย่างง่ายดายด้วย:

SELECT DISTINCT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film

ข้อความค้นหานั้น "ผิด" และให้ผลเช่น:

rating   rn
------------
G        1
G        2
G        3
...
G        178
NC-17    179
NC-17    180
...

นี่ไม่ใช่สิ่งที่เราต้องการ การDISTINCTดำเนินการ"เกิดขึ้นหลังจาก"การฉายภาพดังนั้นเราจึงไม่สามารถลบDISTINCTคะแนนได้อีกเพราะฟังก์ชั่นหน้าต่างได้รับการคำนวณและคาดการณ์ไว้แล้ว ในการใช้งานDISTINCTเราจะต้องซ้อนส่วนนั้นของแบบสอบถาม:

SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM (
  SELECT DISTINCT rating FROM film
) f

หมายเหตุด้านข้าง: ในกรณีนี้เราสามารถใช้DENSE_RANK()

SELECT DISTINCT rating, dense_rank() OVER (ORDER BY rating) AS rn
FROM film

2. ไม่สามารถใช้ค่าใด ๆ จากการฉาย

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

นี่คือ SQL ที่ไม่ถูกต้อง:

SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY name

สิ่งนี้ใช้ได้ (การแสดงออกซ้ำ)

SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY first_name || ' ' || last_name

สิ่งนี้ใช้ได้เช่นกัน (ซ้อนการแสดงออก)

SELECT name
FROM (
  SELECT first_name || ' ' || last_name AS name
  FROM customer
) c
GROUP BY name

ฉันได้เขียนเกี่ยวกับหัวข้อนี้ในเชิงลึกมากขึ้นในโพสต์บล็อก


ฉันรู้สึกประหลาดใจอย่างยิ่งที่เห็นว่าคำสั่งของการประหารชีวิตไม่ได้ถูกกล่าวถึงในคำถามนี้ทันที ขอบคุณมากอธิบายอย่างมากเช่นกัน ในประเด็นของคุณ 2. บางคน (หนึ่ง?) db ของอนุญาตให้ใช้ชื่อแทนเลือกตลอดแบบสอบถาม (หนึ่งที่ฉันรู้คือ Teradata แต่มันเป็นข้อยกเว้น)
Used_By_Already

@Used_By_Already: แน่นอนว่าบางฐานข้อมูลทำเช่นนั้น ฐานข้อมูลจำนวนมากอนุญาตให้ใช้นามแฝงเหล่านั้นในบางส่วนเท่านั้น (เช่นไม่ใช่WHEREแต่อาจจะGROUP BY) ไม่ว่าในกรณีใดฉันคิดว่ามันเป็นความคิดที่ไม่ดีและฉันไม่แนะนำให้ใช้คุณสมบัตินี้เพื่อเหตุผลในการพกพาและการบำรุงรักษา "ทันใด" มันจะไม่ทำงานอีกต่อไปเช่นเมื่อใช้ชื่อแทนฟังก์ชันการรวมหรือฟังก์ชันหน้าต่าง
Lukas Eder

never using that feature for portability and maintenance reasons!! ตกลง 100% ... และตอนนี้ฉันก็กำลังออกความเห็นบล็อกของคุณเช่นกันผลงานยอดเยี่ยม ไชโย
Used_By_Already

32

ใช้DISTINCTหากคุณต้องการลบรายการที่ซ้ำ ใช้GROUPY BYถ้าคุณต้องการที่จะนำไปใช้ประกอบการรวม ( MAX, SUM, GROUP_CONCAT, ... , หรือHAVINGข้อ)


19

ฉันคาดหวังว่ามีความเป็นไปได้สำหรับความแตกต่างเล็กน้อยในการดำเนินการของพวกเขา ฉันตรวจสอบแผนการดำเนินการสำหรับข้อความค้นหาที่เทียบเท่าสองหน้าที่ตามบรรทัดเหล่านี้ใน Oracle 10g:

core> select sta from zip group by sta;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH GROUP BY     |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

core> select distinct sta from zip;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH UNIQUE       |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

การดำเนินการตรงกลางนั้นแตกต่างกันเล็กน้อย: "HASH GROUP BY" กับ "HASH UNIQUE" แต่ค่าใช้จ่ายโดยประมาณ ฯลฯ นั้นเหมือนกัน ฉันดำเนินการสิ่งเหล่านี้ด้วยการติดตามและการดำเนินการนับที่แท้จริงนั้นเหมือนกันสำหรับทั้งสอง (ยกเว้นว่าสิ่งที่สองไม่จำเป็นต้องอ่านทางกายภาพใด ๆ เนื่องจากการแคช)

แต่ฉันคิดว่าเนื่องจากชื่อการดำเนินการที่แตกต่างกันการดำเนินการจะปฏิบัติตามเส้นทางรหัสที่แตกต่างกันบ้างและเปิดโอกาสให้ความแตกต่างที่สำคัญ

ฉันคิดว่าคุณควรชอบไวยากรณ์ DISTINCT สำหรับวัตถุประสงค์นี้ มันไม่ใช่แค่นิสัยมันชัดเจนมากขึ้นบ่งบอกถึงวัตถุประสงค์ของแบบสอบถาม


14

สำหรับแบบสอบถามที่คุณโพสต์พวกเขาเหมือนกัน แต่สำหรับข้อความค้นหาอื่น ๆ ที่อาจไม่เป็นจริง

ตัวอย่างเช่นมันไม่เหมือนกับ:

SELECT C FROM myTbl GROUP BY C, D

14

ฉันอ่านความคิดเห็นทั้งหมดข้างต้น แต่ไม่เห็นใครเลยชี้ให้เห็นถึงความแตกต่างที่สำคัญระหว่าง Group By และ Distinct นอกเหนือจากบิตการรวม

Distinct ส่งคืนแถวทั้งหมดจากนั้นทำซ้ำในขณะที่ Group By ยกเลิกการทำซ้ำแถวเนื่องจากอัลกอริทึมอ่านทีละตัว

ซึ่งหมายความว่าพวกเขาสามารถให้ผลลัพธ์ที่แตกต่าง!

ตัวอย่างเช่นรหัสด้านล่างสร้างผลลัพธ์ที่แตกต่าง:

SELECT distinct ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable

 SELECT ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable
GROUP BY Name

หากมี 10 ชื่อในตารางที่ 1 ซึ่งเป็นชื่อซ้ำกันดังนั้นแบบสอบถามแรกจะส่งกลับ 10 แถวในขณะที่แบบสอบถามที่สองส่งคืน 9 แถว

เหตุผลคือสิ่งที่ฉันพูดไว้ข้างต้นเพื่อให้พวกเขาสามารถทำงานได้แตกต่างกัน!


11
นั่นเป็นเพราะในขณะที่คุณจัดกลุ่มตามNameในการสืบค้นที่สองdistinctคำหลักจะใช้กับทั้งคอลัมน์Nameและคอลัมน์ของคุณROW_NUMBER()ในส่วนselectคำสั่งแรก หากคุณจัดกลุ่มตามคอลัมน์แรกในแบบสอบถามที่สองแบบสอบถามจะส่งกลับผลลัพธ์เดียวกัน

นี่คือเกิดผลการของorder of executionของคำสั่ง SQL ซึ่งเป็น (ในความหมายทั่วไป) FROM and ON (joins), WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT / OFFSET / TOPดังนั้นแบบสอบถามที่สองชื่อจะลดลงในจำนวนโดยกลุ่มโดยและต่อมา row_number () ถูกนำไปใช้ผลในหนึ่งแถว ต่อชื่อที่ไม่ซ้ำ ในเคียวรีแรก row_number () ถูกนำไปใช้ก่อนที่จะใช้ความแตกต่างและเนื่องจากลักษณะของฟังก์ชัน row_number () ทุกแถวจะได้รับจำนวนเต็มเฉพาะดังนั้นทุกแถวจะถูกส่งกลับแม้ว่าจะมีค่าชื่อซ้ำ
Used_By_Already

12

หากคุณใช้ DISTINCT ที่มีหลายคอลัมน์ชุดผลลัพธ์จะไม่ถูกจัดกลุ่มตามที่มันจะเป็น GROUP BY และคุณไม่สามารถใช้ฟังก์ชั่นรวมกับ DISTINCT


11

พวกเขามีความหมายที่แตกต่างกันแม้ว่าพวกเขาจะมีผลลัพธ์ที่เท่าเทียมกันในข้อมูลเฉพาะของคุณ


6

GROUP BY มีความหมายที่เฉพาะเจาะจงมากซึ่งแตกต่าง (heh) จากฟังก์ชัน DISTINCT

GROUP BY ทำให้ผลลัพธ์ของแบบสอบถามถูกจัดกลุ่มโดยใช้นิพจน์ที่เลือกจากนั้นฟังก์ชันรวมจะถูกนำไปใช้และสิ่งเหล่านี้จะทำงานกับแต่ละกลุ่มแทนที่จะเป็นทั้งชุดผลลัพธ์

นี่คือตัวอย่างที่อาจช่วยได้:

รับตารางที่มีลักษณะดังนี้:

name
------
barry
dave
bill
dave
dave
barry
john

แบบสอบถามนี้:

SELECT name, count(*) AS count FROM table GROUP BY name;

จะสร้างผลลัพธ์เช่นนี้:

name    count
-------------
barry   2
dave    3
bill    1
john    1

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


6

โปรดอย่าใช้ GROUP BY เมื่อคุณหมายถึง DISTINCT แม้ว่าพวกเขาจะทำงานแบบเดียวกันก็ตาม ฉันสมมติว่าคุณกำลังพยายามตัดมิลลิวินาทีออกจากข้อความค้นหาและฉันต้องชี้ให้เห็นว่าเวลาของนักพัฒนาซอฟต์แวร์นั้นมีขนาดใหญ่กว่าคอมพิวเตอร์


5

หากคุณใช้ GROUP BY โดยไม่มีฟังก์ชันการรวมใด ๆ ภายในจะถือว่าเป็น DISTINCT ดังนั้นในกรณีนี้จะไม่มีความแตกต่างระหว่าง GROUP BY และ DISTINCT

แต่เมื่อคุณได้รับประโยค DISTINCT ที่ดีกว่าเพื่อใช้สำหรับค้นหาระเบียนที่ไม่ซ้ำกันของคุณเพราะวัตถุประสงค์ของ GROUP BY คือการรวมกลุ่ม


4

กลุ่มโดยใช้ในการดำเนินการรวม - เช่นเมื่อคุณต้องการนับจำนวน Bs แยกตามคอลัมน์ C

select C, count(B) from myTbl group by C

เสียงที่แตกต่างคืออะไร - คุณจะได้แถวที่ไม่ซ้ำใคร

ใน sql server 2005 ดูเหมือนว่าเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาสามารถปรับความแตกต่างในตัวอย่างง่าย ๆ ที่ฉันใช้ Dunno ถ้าคุณวางใจได้ในทุกสถานการณ์


3

ในแบบสอบถามเฉพาะนั้นไม่มีความแตกต่าง แต่แน่นอนถ้าคุณเพิ่มคอลัมน์รวมใด ๆ คุณจะต้องใช้กลุ่มโดย


3

ในมุมมอง Teradata :

จากมุมมองชุดผลลัพธ์มันไม่สำคัญว่าคุณจะใช้ DISTINCT หรือ GROUP BY ใน Teradata หรือไม่ ชุดคำตอบจะเหมือนกัน

จากมุมมองประสิทธิภาพมันไม่เหมือนกัน

เพื่อให้เข้าใจถึงผลกระทบต่อประสิทธิภาพการทำงานคุณต้องทราบว่าเกิดอะไรขึ้นกับ Teradata เมื่อดำเนินการคำสั่งด้วย DISTINCT หรือ GROUP BY

ในกรณีของ DISTINCT แถวจะถูกกระจายใหม่ทันทีโดยไม่มีการกระจายล่วงหน้าใด ๆ ในขณะที่ในกรณีของ GROUP BY ในขั้นตอนแรกจะมีการทำ preaggregation และค่าที่ไม่ซ้ำกันจะกระจายไปทั่ว AMPs

อย่าคิดว่าตอนนี้ GROUP BY ดีกว่าเสมอจากมุมมองประสิทธิภาพ เมื่อคุณมีค่าที่แตกต่างกันจำนวนมากขั้นตอน preaggregation ของ GROUP BY นั้นไม่มีประสิทธิภาพมากนัก Teradata ต้องจัดเรียงข้อมูลเพื่อลบรายการที่ซ้ำกัน ในกรณีนี้มันอาจจะดีกว่าการแจกจ่ายซ้ำก่อนเช่นใช้คำสั่ง DISTINCT เฉพาะในกรณีที่มีค่าที่ซ้ำกันจำนวนมากคำสั่ง GROUP BY อาจเป็นตัวเลือกที่ดีกว่าเนื่องจากจะมีเพียงขั้นตอนการขจัดความซ้ำซ้อนหลังจากการแจกจ่ายซ้ำ

ในระยะสั้น DISTINCT กับ GROUP BY ใน Teradata หมายถึง:

GROUP BY -> สำหรับการซ้ำซ้อนหลายครั้ง DISTINCT -> ไม่มีหรือซ้ำกันสองสามเท่านั้น ในบางครั้งเมื่อใช้ DISTINCT คุณมีพื้นที่สปูลหมดใน AMP เหตุผลก็คือการแจกจ่ายซ้ำเกิดขึ้นทันทีและการบิดเบือนอาจทำให้แอมป์หมดพื้นที่

หากสิ่งนี้เกิดขึ้นคุณอาจมีโอกาสที่ดีขึ้นเมื่อ GROUP BY เนื่องจากข้อมูลซ้ำถูกลบไปแล้วในขั้นตอนแรกและมีการย้ายข้อมูลน้อยลงใน AMP


คือTeradataอะไร
Brettski

Teradata เป็นระบบจัดการฐานข้อมูลเชิงสัมพันธ์ (RDBMS) สามารถรองรับผู้ใช้พร้อมกันจำนวนมากจากแพลตฟอร์มไคลเอนต์ที่หลากหลาย Teradata เข้ากันได้กับมาตรฐาน ANSI และสร้างขึ้นอย่างสมบูรณ์บนสถาปัตยกรรมคู่ขนาน
Ram Ghadiyaram

2

จากมุมมอง 'ภาษา SQL' มุมมองทั้งสองของการสร้างนั้นเท่ากันและสิ่งที่คุณเลือกเป็นหนึ่งในตัวเลือก 'ไลฟ์สไตล์' ที่เราทุกคนต้องทำ ฉันคิดว่ามีกรณีที่ดีสำหรับ DISTINCT ที่ชัดเจนยิ่งขึ้น (และดังนั้นจึงมีความเห็นอกเห็นใจต่อบุคคลที่จะสืบทอดรหัสของคุณ ฯลฯ ) แต่นั่นไม่ได้หมายความว่า GROUP BY build เป็นตัวเลือกที่ไม่ถูกต้อง

ฉันคิดว่านี่เป็น 'กลุ่มตามสำหรับมวลรวม' คือการเน้นผิด Folk ควรระวังว่าสามารถตั้งค่าฟังก์ชัน (MAX, MIN, COUNT และอื่น ๆ ) เพื่อให้พวกเขาสามารถเข้าใจเจตนาของโค้ดได้เมื่อเป็น

เครื่องมือเพิ่มประสิทธิภาพในอุดมคติจะรับรู้การสร้าง SQL ที่เทียบเท่าและจะเลือกแผนในอุดมคติ สำหรับเครื่องมือ SQL ที่คุณเลือกคุณต้องทดสอบ :)

PS บันทึกตำแหน่งของคำสำคัญ DISTINCT ในส่วนคำสั่งที่เลือกอาจให้ผลลัพธ์ที่แตกต่างเช่นความคมชัด:

SELECT COUNT(DISTINCT C) FROM myTbl;

SELECT DISTINCT COUNT(C) FROM myTbl;

1

คุณสังเกตเห็นเพียงเพราะคุณกำลังเลือกคอลัมน์เดียว

ลองเลือกสองฟิลด์แล้วดูว่าเกิดอะไรขึ้น

จัดกลุ่มโดยมีวัตถุประสงค์เพื่อใช้ในลักษณะนี้:

SELECT name, SUM(transaction) FROM myTbl GROUP BY name

ซึ่งจะแสดงผลรวมของการทำธุรกรรมทั้งหมดสำหรับแต่ละคน


นี่ไม่ใช่คำถามของการรวม ในตัวอย่างของคุณเลือก c, d จาก mytbl GROUP BY C, D; ในความเป็นจริงจะส่งคืนชุดข้อมูลเดียวกันกับ SELECT DISTINCT C, D จาก mytbl; นี่คือพื้นฐานของคำถาม
Brettski

1

ฉันรู้ว่ามันเป็นโพสต์เก่า แต่มันเกิดขึ้นที่ฉันมีแบบสอบถามที่ใช้กลุ่มโดยเพียงแค่ส่งกลับค่าที่แตกต่างเมื่อใช้แบบสอบถามในคางคกและ oracle รายงานทุกอย่างทำงานได้ดีฉันหมายถึงเวลาตอบสนองที่ดี เมื่อเราย้ายจาก Oracle 9i เป็น 11g เวลาตอบสนองใน Toad นั้นยอดเยี่ยม แต่ใน reporte ใช้เวลาประมาณ 35 นาทีในการทำรายงานให้เสร็จเมื่อใช้เวอร์ชันก่อนหน้านี้ใช้เวลาประมาณ 5 นาที

ทางออกคือการเปลี่ยนกลุ่มโดยและใช้ DISTINCT และตอนนี้รายงานจะทำงานในเวลาประมาณ 30 วินาที

ฉันหวังว่านี่จะเป็นประโยชน์สำหรับคนที่มีสถานการณ์เดียวกัน


1

ในแง่ของการใช้งาน GROUP BY ใช้สำหรับจัดกลุ่มแถวเหล่านั้นที่คุณต้องการคำนวณ DISTINCT จะไม่ทำการคำนวณใด ๆ มันจะไม่แสดงแถวที่ซ้ำกัน

ฉันมักจะใช้ DISTINCT เสมอหากฉันต้องการนำเสนอข้อมูลโดยไม่ซ้ำกัน

หากฉันต้องการคำนวณเช่นรวมจำนวนมะม่วงทั้งหมดฉันจะใช้ GROUP BY


0

วิธีที่ฉันเข้าใจอยู่เสมอคือการใช้งานที่แตกต่างกันเหมือนกับการจัดกลุ่มตามทุกฟิลด์ที่คุณเลือกตามลำดับที่คุณเลือก

เช่น:

select distinct a, b, c from table;

เหมือนกับ:

select a, b, c from table group by a, b, c

ตกลง แต่มันจะเป็นเช่นเดียวกับเลือก c, b, a จากกลุ่มตารางโดย a, b, c
Dheer

ใช่มันจะเหมือนกัน
Caius Jard

0

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


0

ใน Hive (HQL) กลุ่มโดยสามารถเร็วกว่าที่แตกต่างเพราะก่อนหน้านี้ไม่จำเป็นต้องเปรียบเทียบทุกสาขาในตาราง ดูhttps://sqlperformance.com/2017/01/t-sql-queries/surprises-assumptions-group-by-distinct


0

บางครั้งพวกเขาอาจให้ผลลัพธ์ที่เหมือนกัน แต่มีไว้เพื่อใช้ในแง่ที่แตกต่างกัน / กรณี ความแตกต่างที่สำคัญคือในไวยากรณ์

สังเกตตัวอย่างด้านล่างอย่างละเอียด DISTINCTใช้เพื่อกรองชุดของค่าที่ซ้ำกัน (6, cs, 9.1) และ (1, cs, 5.5) เป็นสองชุดที่แตกต่างกัน ดังนั้นDISTINCTจะแสดงทั้งสองแถวในขณะที่GROUP BY Branchจะแสดงเพียงชุดเดียว

 SELECT * FROM student; 
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    2 | mech   |  6.3 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    1 | cs     |  5.5 |
+------+--------+------+
5 rows in set (0.001 sec)

SELECT DISTINCT * FROM student; 
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    2 | mech   |  6.3 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    1 | cs     |  5.5 |
+------+--------+------+
5 rows in set (0.001 sec)

SELECT * FROM student GROUP BY Branch;
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    2 | mech   |  6.3 |
+------+--------+------+
4 rows in set (0.001 sec)

บางครั้งผลลัพธ์ที่สามารถทำได้โดยGROUP BYข้อไม่สามารถทำได้โดยDISTINCTไม่ต้องใช้ประโยคหรือเงื่อนไขพิเศษบางอย่าง เช่นในกรณีข้างต้น

เพื่อให้ได้ผลลัพธ์เดียวกันกับที่DISTINCTคุณต้องส่งชื่อคอลัมน์ทั้งหมดGROUP BYตามข้อเช่นด้านล่าง ดังนั้นดูความแตกต่างของประโยค คุณต้องมีความรู้เกี่ยวกับชื่อคอลัมน์ทั้งหมดเพื่อใช้GROUP BYส่วนคำสั่งในกรณีนั้น

SELECT * FROM student GROUP BY Id, Branch, CGPA;
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    1 | cs     |  5.5 |
|    2 | mech   |  6.3 |
|    3 | civil  |  7.2 |
|    4 | eee    |  8.2 |
|    6 | cs     |  9.1 |
+------+--------+------+

นอกจากนี้ฉันได้สังเกตเห็นGROUP BYแสดงผลลัพธ์ในลำดับจากน้อยไปมากซึ่งDISTINCTไม่ได้ แต่ฉันไม่แน่ใจเกี่ยวกับเรื่องนี้ มันอาจจะแตกต่างจากผู้ขายที่ชาญฉลาด

ที่มา: https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by


0

โดยทั่วไปเราสามารถใช้DISTINCTสำหรับกำจัดรายการที่ซ้ำกันในคอลัมน์ที่ระบุในตาราง

ในกรณีที่ 'GROUP BY' เราสามารถใช้ฟังก์ชั่นการรวมเช่น AVG, MAX, MIN, SUMและCOUNTในคอลัมน์ที่เฉพาะเจาะจงและเรียกชื่อคอลัมน์และมันรวมตัวฟังก์ชั่นผลในคอลัมน์เดียวกัน

ตัวอย่าง:

select  specialColumn,sum(specialColumn) from yourTableName group by specialColumn;

-1

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

ลองตัวอย่างง่ายๆ

ประกาศตาราง @tmpresult (รหัส Tinyint)

แทรกลงใน @tmpresult เลือก 5 รวมทั้งหมดเลือก 2 รวมทั้งหมดเลือก 3 รวมทั้งหมดเลือก 4

เลือก Id ที่แตกต่างกันจาก @tmpresult


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