ส่วนของการค้นหากำลังขยาย CPU เป็นระยะเวลานานคือฟังก์ชันในส่วน GROUP BY clause และข้อเท็จจริงที่ว่าการจัดกลุ่มนั้นจะต้องมีการเรียงลำดับที่ไม่ได้ทำดัชนีในอินสแตนซ์นี้เสมอ ในขณะที่ดัชนีในฟิลด์การประทับเวลาจะช่วยให้ตัวกรองเริ่มต้นการดำเนินการนี้จะต้องดำเนินการในทุกแถวที่ตัวกรองจับคู่ การเร่งความเร็วนี้กำลังใช้เส้นทางที่มีประสิทธิภาพมากขึ้นในการทำงานเช่นเดียวกับที่อเล็กซ์แนะนำ แต่คุณก็ยังมีความไร้ประสิทธิภาพอยู่ที่นั่นเพราะการรวมฟังก์ชั่นที่คุณเคยใช้กับตัววางแผนแบบสอบถามจะไม่สามารถเกิดขึ้นได้ สิ่งที่จะได้รับการช่วยเหลือจากดัชนีใด ๆ ดังนั้นจึงจะต้องเรียกใช้ผ่านทุกแถวก่อนที่จะเรียกใช้ฟังก์ชันเพื่อคำนวณค่าการจัดกลุ่มจากนั้นสามารถสั่งข้อมูลและคำนวณผลรวมของการจัดกลุ่มที่เกิดขึ้นได้
ดังนั้นวิธีการแก้ปัญหาคือการทำให้กลุ่มกระบวนการโดยสิ่งที่มันสามารถใช้ดัชนีหรือลบความจำเป็นที่จะต้องพิจารณาแถวที่ตรงกันทั้งหมดในครั้งเดียว
คุณสามารถรักษาคอลัมน์พิเศษสำหรับแต่ละแถวที่มีเวลาปัดเศษเป็นชั่วโมงและจัดทำดัชนีคอลัมน์นี้เพื่อใช้ในแบบสอบถามดังกล่าว นี่คือการทำให้ข้อมูลของคุณเสื่อมสภาพดังนั้นอาจรู้สึกว่า "สกปรก" แต่จะใช้งานได้และจะสะอาดกว่าการแคชมวลรวมทั้งหมดเพื่อใช้ในอนาคต (และอัปเดตแคชนั้นเมื่อมีการเปลี่ยนแปลงข้อมูลพื้นฐาน) คอลัมน์พิเศษควรได้รับการบำรุงรักษาโดยทริกเกอร์หรือเป็นคอลัมน์ที่คำนวณแล้วจะยังคงอยู่โดยไม่ได้รับการบำรุงรักษาด้วยตรรกะที่อื่นเนื่องจากจะรับประกันตำแหน่งปัจจุบันและอนาคตทั้งหมดที่อาจแทรกข้อมูลหรืออัปเดตคอลัมน์ประทับเวลาหรือแถวที่มีอยู่ คอลัมน์. คุณยังสามารถลบ MIN (การประทับเวลา) ออกได้ สิ่งที่แบบสอบถามจะส่งผลให้ในลักษณะนี้ยังคงเดินลงแถวทั้งหมด (นี้ไม่สามารถหลีกเลี่ยงได้ชัด) แต่มันสามารถทำดัชนีเพื่อ เอาท์พุทแถวสำหรับการจัดกลุ่มแต่ละกลุ่มตามที่ได้รับไปยังค่าถัดไปในดัชนีแทนที่จะต้องจดจำชุดของแถวทั้งหมดสำหรับการดำเนินการเรียงลำดับที่ไม่ได้จัดทำดัชนีก่อนที่จะทำการจัดกลุ่ม / การรวมได้ มันจะใช้หน่วยความจำน้อยลงเช่นกันเนื่องจากไม่จำเป็นต้องจำแถวใด ๆ จากค่าการจัดกลุ่มก่อนหน้าเพื่อประมวลผลแถวที่กำลังดูอยู่ตอนนี้หรือที่เหลือ
วิธีการนั้นจะลบความต้องการค้นหาบางอย่างในหน่วยความจำสำหรับชุดผลลัพธ์ทั้งหมดและทำการเรียงลำดับที่ไม่ได้ทำดัชนีสำหรับการดำเนินการกลุ่มและลบการคำนวณค่ากลุ่มออกจากแบบสอบถามขนาดใหญ่ (ย้ายงานนั้นออกไปยัง INSERTs / UPDATE ข้อมูล) และควรอนุญาตให้แบบสอบถามดังกล่าวสามารถทำงานได้อย่างยอมรับได้โดยไม่จำเป็นต้องเก็บรักษาผลลัพธ์ที่รวบรวมไว้แยกจากกัน
วิธีการที่ไม่ทำให้ข้อมูลของคุณว่างเปล่า แต่ยังต้องการโครงสร้างเพิ่มเติมคือใช้ "ตารางเวลา" ในกรณีนี้ตารางหนึ่งมีหนึ่งแถวต่อชั่วโมงตลอดเวลาที่คุณต้องการพิจารณา ตารางนี้จะไม่ใช้พื้นที่จำนวนมากใน DB หรือขนาดที่ประเมินได้ - เพื่อครอบคลุมช่วงเวลา 100 ปีต่อตารางที่มีหนึ่งแถวของสองวันที่ (จุดเริ่มต้นและจุดสิ้นสุดของชั่วโมงเช่น '2011-01-01 @ 00: 00: 00.0000 ',' 2011-01-01 @ 00: 00: 59.9997 ', "9997" เป็นจำนวนมิลลิวินาทีที่น้อยที่สุดในฟิลด์ DATETIME จะไม่ปัดขึ้นเป็นวินาทีถัดไป) ซึ่งเป็นส่วนหนึ่งของ คีย์หลักที่ทำคลัสเตอร์จะใช้พื้นที่ ~ 14Mbyte (8 + 8 ไบต์ต่อแถว * 24 ชั่วโมง / วัน * 365.25 วัน / ปี * 100 บวกบิตสำหรับค่าใช้จ่ายของโครงสร้างต้นไม้ดัชนีดัชนี แต่ค่าใช้จ่ายนั้นไม่มีนัยสำคัญ) .
SELECT CONVERT(VARCHAR, [timestamp], 1)+' '+ CAST(DATEPART(Hh,[timestamp]) as VARCHAR) AS TimeStampHour
, MIN([timestamp]) as TimeStamp
, AVG(MyField) As AvgField
FROM TimeRangeByHours tt
INNER JOIN MyData md ON md.TimeStamp BETWEEN tt.StartTime AND tt.EndTime
WHERE tt.StartTime > '4/10/2011'
GROUP BY tt.StartTime
ORDER BY tt.StartTime
ซึ่งหมายความว่าตัววางแผนคิวรีสามารถจัดเรียงดัชนีใน MyData.TimeStamp ที่จะใช้ ตัววางแผนคิวรีควรมีความสว่างเพียงพอที่จะคำนวณว่ามันสามารถเดินลงตารางเชื่องในขั้นตอนที่มีดัชนีบน MyData.TimeStamp อีกครั้งหนึ่งแถวต่อกลุ่มเอาท์พุทเอาท์พุทอีกครั้งและทิ้งแต่ละชุด ไม่มีการจัดเก็บแถวกลางทั้งหมดที่ไหนสักแห่งใน RAM จากนั้นทำการเรียงลำดับที่ไม่ได้จัดทำดัชนีไว้ แน่นอนว่าวิธีนี้ต้องการให้คุณสร้างตารางเวลาและตรวจสอบให้แน่ใจว่ามันครอบคลุมทั้งหลังไปข้างหน้าและข้างหลังมากพอ แต่คุณสามารถใช้ตารางเวลาสำหรับการสืบค้นกับเขตข้อมูลวันที่จำนวนมากในแบบสอบถามที่แตกต่างกัน คอลัมน์ที่คำนวณพิเศษสำหรับแต่ละฟิลด์วันที่ที่คุณต้องการกรอง / กลุ่มด้วยวิธีนี้และขนาดที่เล็กของตาราง (ยกเว้นว่าคุณต้องการให้มีช่วง 10
วิธีการตารางเวลามีความแตกต่างพิเศษ (ที่อาจเป็นประโยชน์มาก) เมื่อเทียบกับสถานการณ์ปัจจุบันของคุณและวิธีการคำนวณคอลัมน์: มันสามารถคืนแถวในช่วงเวลาที่ไม่มีข้อมูลเพียงแค่เปลี่ยน INNER JOIN ในแบบสอบถามตัวอย่างด้านบน เป็นคนซ้ายอย่างเดียว
บางคนแนะนำไม่ให้มีตารางเวลาแบบฟิสิคัล แต่กลับมาจากฟังก์ชั่นส่งคืนตารางแทนเสมอ ซึ่งหมายความว่าเนื้อหาของตารางเวลาไม่เคยถูกเก็บไว้ในดิสก์ (หรือต้องอ่านจาก) และถ้าฟังก์ชั่นนั้นเขียนได้ดีคุณไม่ต้องกังวลว่าตารางเวลาจะต้องใช้เวลานานแค่ไหน แต่ฉัน สงสัยค่าใช้จ่ายซีพียูในการสร้างตารางในหน่วยความจำสำหรับบางแถวทุกแบบสอบถามมีค่าน้อยกว่าการประหยัดความยุ่งยากในการสร้าง (และการบำรุงรักษาหาก timespan ต้องขยายเกินขีด จำกัด รุ่นแรกของคุณ) ตารางเวลาทางกายภาพ
หมายเหตุด้านข้าง: คุณไม่จำเป็นต้องใช้ประโยค DISTINCT ในข้อความค้นหาเดิมของคุณ การจัดกลุ่มจะทำให้แน่ใจว่าแบบสอบถามเหล่านี้ส่งคืนหนึ่งแถวต่อรอบระยะเวลาที่พิจารณาเท่านั้นดังนั้น DISTINCT จะไม่ทำอะไรเลยนอกจากปั่น CPU อีกเล็กน้อย (เว้นแต่ผู้วางแผนแบบสอบถามจะสังเกตเห็นว่าความแตกต่างนั้นจะไม่ใช่แบบไม่มีตัวเลือก) เพิกเฉยและไม่ใช้เวลา CPU เพิ่ม)