คอลัมน์ที่ไม่เกี่ยวข้องมีผลต่อเวลาสอบถามของข้อความสั่งที่เลือกหรือไม่


10

ฉันแค่อยากรู้

สมมติว่าคุณมีตาราง 1 ล้านระเบียน / แถว

select order_value from store.orders

มันสร้างความแตกต่างหรือไม่ว่าตารางนั้นมี 1 เขตข้อมูล 2 เขตข้อมูลหรือ 100 เขตข้อมูลในเวลาสอบถามจริงหรือไม่ ฉันหมายถึงฟิลด์ทั้งหมดที่ไม่ใช่ "order_value"

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


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

คำตอบ:


10

สิ่งนี้ขึ้นอยู่กับดัชนีและประเภทข้อมูล

ตัวอย่างการใช้ฐานข้อมูล Stack Overflow นี่คือลักษณะที่ตารางผู้ใช้มีลักษณะดังนี้:

ถั่ว

มันมี PK / CX ในคอลัมน์ Id ดังนั้นมันจึงเป็นข้อมูลตารางทั้งหมดที่เรียงลำดับตาม Id

ด้วยสิ่งนั้นเป็นดัชนีเพียงอย่างเดียว SQL ต้องอ่านสิ่งนั้นทั้งหมด (ส่งคอลัมน์ LOB) ไปยังหน่วยความจำหากยังไม่มีอยู่

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SET STATISTICS TIME, IO ON 

SELECT u.Id
INTO  #crap1
FROM dbo.Users AS u

เวลาสถิติและโปรไฟล์ io มีลักษณะดังนี้:

Table 'Users'. Scan count 7, logical reads 80846, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2406 ms,  elapsed time = 446 ms.

ถ้าฉันเพิ่มดัชนีแบบ nonclustered เพิ่มเติมใน Just Id

CREATE INDEX ix_whatever ON dbo.Users (Id)

ตอนนี้ฉันมีดัชนีที่เล็กกว่ามากซึ่งตรงกับคำค้นหาของฉัน

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SELECT u.Id
INTO  #crap2
FROM dbo.Users AS u

รายละเอียดที่นี่:

Table 'Users'. Scan count 7, logical reads 6587, physical reads 0, read-ahead reads 6549, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2344 ms,  elapsed time = 384 ms.

เราสามารถอ่านและลดเวลาซีพียูได้น้อยลง

หากไม่มีข้อมูลเพิ่มเติมเกี่ยวกับคำนิยามตารางของคุณฉันไม่สามารถลองทำซ้ำสิ่งที่คุณพยายามวัดได้ดีกว่า

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

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

ใช้ตัวอย่างสมุดโทรศัพท์ ol ': แม้ว่าคุณจะเพิ่งอ่านหมายเลขโทรศัพท์เมื่อคุณเปลี่ยนหน้าคุณจะเปลี่ยนนามสกุลชื่อที่อยู่ ฯลฯ พร้อมด้วยหมายเลขโทรศัพท์


@ jpmc26 มันอาจแย่กว่านั้นเพราะถ้าคอลัมน์ที่ร้องขอนั้นเป็นส่วนหนึ่งของดัชนีการสืบค้นสามารถทำได้เพียงแค่ดูที่ดัชนี หากคอลัมน์ไม่ได้จัดทำดัชนีพวกเขาสามารถทำให้ระเบียนหลักที่จะโหลดและแม้กระทั่งระเบียนรองสำหรับประเภทตาราง / คอลัมน์ที่ไม่ได้รับการรับรอง
Christopher Schultz

12

ขึ้นอยู่กับโครงสร้างของตารางและดัชนีที่มี

  • กรณี A: ร่วม (rowstore) (order_value)ตารางดัชนีที่ไม่มีใน

    แผนการดำเนินการที่เป็นไปได้เพียงอย่างเดียวคือการอ่านตารางทั้งหมด (ซึ่งแน่นอนว่าแตกต่างกันมากเมื่อเป็น 2 กับ 200 คอลัมน์ดังนั้นกว้างไม่กี่พันสองสามพันไบต์)

  • กรณี B: ตารางทั่วไปมีดัชนี(order_value)หรือดัชนีอื่น ๆ ที่รวมคอลัมน์นั้น

    มีแผนดีกว่าตอนนี้สแกนดัชนีทั้งหมด (หนึ่งในนั้น) - ซึ่งแน่นอนว่าแคบกว่าทั้งตารางมากเพียงไม่กี่ไบต์ ซึ่งไม่เกี่ยวข้องหากตารางมี 2 หรือ 200 คอลัมน์ สแกนดัชนีเท่านั้น

  • กรณี C: เป็นตารางคอลัมน์

    ดังที่ชื่อแสดงถึงโครงสร้างของตารางเหล่านี้เป็นแบบคอลัมน์แบบฉลาดไม่ใช่แบบแบบแถว ไม่จำเป็นต้องมีดัชนีใด ๆ การออกแบบตารางนั้นเหมาะสำหรับการอ่านคอลัมน์ทั้งหมด


ความรู้ของฉันเป็นสีเขียวเล็กน้อยในเรื่องนี้ เป็นธรรมดาที่สุด (พูดฐานข้อมูล SQL Server ทั่วไป) มีตาราง rowstore ถูกต้องหรือไม่ เหตุใดจึงต้องสแกนทั้งตารางหากจำเป็นต้องส่งคืนหนึ่งคอลัมน์ / ฟิลด์ นี่เป็นเพียงการออกแบบตาราง rowstore หรือไม่
user45867

@ user45867 ใช่ข้อมูลจะถูกเก็บไว้ในแถว (ยกเว้นคอลัมน์ที่มีขนาดใหญ่มากซึ่งถูกเก็บไว้ภายนอก) เมื่อ SQL Server อ่านจากดิสก์มันจะอ่านในบล็อกทั้งหมดจะไม่สามารถอ่านเฉพาะส่วนที่มีหนึ่งคอลัมน์
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.