ความแตกต่างระหว่างจำนวนที่เลือก (*) และจำนวนที่เลือก (any_non_null_column) คืออะไร


58

ฉันดูเหมือนจะจำไว้ว่า (ใน Oracle) มีความแตกต่างระหว่างการเปล่งเสียงและselect count(*) from any_tableselect count(any_non_null_column) from any_table

อะไรคือความแตกต่างระหว่างสองข้อความนี้ถ้ามี?

คำตอบ:


72
  • COUNT (*) จะรวม NULLS
  • COUNT (column_or_expression) จะไม่

วิธีนี้COUNT(any_non_null_column)จะให้เหมือนกับCOUNT(*)ของหลักสูตรเนื่องจากไม่มีค่า NULL ที่ทำให้เกิดความแตกต่าง

โดยทั่วไปCOUNT(*)ควรจะดีกว่าเพราะดัชนีใด ๆ ที่สามารถใช้ได้เพราะCOUNT(column_or_expression)อาจไม่ได้รับการจัดทำดัชนีหรือ SARGable

จากANSI-92 (มองหา " Scalar expressions 125")

กรณี:

a) หากระบุ COUNT (*) ผลที่ได้คือ cardinality ของ T

b) มิฉะนั้นให้ TX เป็นตารางคอลัมน์เดี่ยวที่เป็นผลลัพธ์ของการใช้ <value expression> กับแต่ละแถวของ T และกำจัดค่า Null หากมีการยกเลิกค่า Null หนึ่งค่าขึ้นไปเงื่อนไขการเติมจะถูกยกขึ้น: คำเตือน - ค่า Null จะถูกตัดออกในฟังก์ชัน set

กฎเดียวกันนี้ใช้กับ SQL Server และ Sybase อย่างน้อยที่สุด

หมายเหตุ: COUNT (1) เหมือนกับ COUNT (*) เนื่องจาก 1 เป็นนิพจน์ที่ไม่เป็นโมฆะ


4
เพื่อความสมบูรณ์: ออราเคิลจะใช้การสแกนดัชนีในคอลัมน์ที่ไม่เป็นโมฆะหากcount(*)มีการใช้ดัชนี
a_horse_with_no_name

ผมคิดว่าในสามตัวเลือกที่เป็นไปได้มีCOUNT(*), COUNT(<constant>)และCOUNT(<column name>)และว่าทั้งสามจะนำหน้าด้วยALLหรือDISTINCT(ผิดนัดALLหากละเว้น) ฉันแค่สงสัยว่าการแสดงออกสามารถใช้ที่คุณพูด_or_expression?
oneday เมื่อ

2
@onedaywhen เป็นตัวอย่างที่ไม่มีประโยชน์ก็เป็นเช่นเดียวกับCOUNT(1) เป็นตัวอย่างที่นับแถวที่ a> b COUNT(*)COUNT(CASE WHEN a>b THEN 1 END)
ypercubeᵀᴹ

16

ในเร็ว ๆ (เช่นใด8.x + ) เวอร์ชั่นของออราเคิลที่พวกเขาทำสิ่งเดียวกัน ความแตกต่างเพียงอย่างเดียวคือความหมาย:

select count(*) from any_table

สามารถอ่านได้ง่ายและชัดเจนในสิ่งที่คุณพยายามจะทำและ

select count(any_non_null_column) from any_table

อ่านยากกว่าเพราะ

  1. มันยาวกว่า
  2. มันเป็นที่รู้จักน้อย
  3. คุณต้องคิดก่อนว่าจะany_non_null_columnมีผลบังคับใช้จริงหรือไม่not null

ในระยะสั้นให้ใช้count(*)


9

ในรุ่นล่าสุดไม่มีความแตกต่างระหว่าง count (*) และ count ( คอลัมน์ใด ๆ ที่ไม่ใช่ null ) โดยเน้นที่ไม่ใช่ null :-) โดยไม่ได้ตั้งใจครอบคลุมหัวข้อนั้นด้วยโพสต์บล็อก: นับ (col) ดีกว่าการนับ (*)?


1

ในหนังสือคู่มือการสอบ Oracle8i Certified Professional DBA (ไอ 0072130601)หน้า 78 บอกว่า COUNT (1) จะทำงานได้เร็วกว่าCOUNT (*)เพราะกลไกบางอย่างถูกเรียกเข้ามาเล่นเพื่อตรวจสอบพจนานุกรมข้อมูลสำหรับทุกคอลัมน์ของคอลัมน์ (หรือ อย่างน้อยคอลัมน์แรกที่ไม่ใช่ nullability) เมื่อใช้COUNT (*) COUNT (1) ข้ามกลไกเหล่านั้น

กลโกง MySQL สำหรับ 'SELECT COUNT (1) บน tblname;' บนตาราง MyISAM โดยการอ่านส่วนหัวของตารางสำหรับการนับตาราง InnoDB นับทุกครั้ง

ในการทดสอบว่า COUNT (1) จะทำงานเร็วกว่า COUNT (*) ในแบบไม่เชื่อเรื่องฐานข้อมูลหรือไม่เพียงแค่เรียกใช้สิ่งต่อไปนี้และตัดสินเวลาทำงานด้วยตัวคุณเอง:

SELECT COUNT(1) FROM tblname WHERE 1 = 1;
SELECT COUNT(*) FROM tblname WHERE 1 = 1;
SELECT COUNT(column-name) FROM tblname WHERE 1 = 1;

สิ่งนี้ทำให้ฟังก์ชั่น COUNT ทำงานบนสนามเด็กเล่นในระดับเดียวกันโดยไม่คำนึงถึงเครื่องมือเก็บข้อมูลหรือ RDBMS


8
คู่มือสอบผิด ใน Oracle count (*) = count (1) (อย่างน้อยหลังจากเวอร์ชัน 7) ดูasktom.oracle.com/pls/asktom/ … (อ้างอิงโดย @JackPDouglas แล้ว)
Leigh Riffel

3
น่าสนใจ COUNT (*) ไม่ควรตรวจสอบคอลัมน์เลยตามข้อกำหนด ANSI ถูกถามเกี่ยวกับ SO สำหรับ SQL Server เมื่อไม่นานมานี้stackoverflow.com/questions/1221559/count-vs-count1/…
gbn

@gbn, @Leigh Riffel, @bernd_k ขอบคุณที่พูดคุยและเตือนให้ฉันอ่านและเรียนรู้เพิ่มเติมโดยเฉพาะอย่างยิ่งเมื่อฉันไม่ได้ทำงานกับ Oracle มาระยะหนึ่งแล้ว
RolandoMySQLDBA
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.