ในการตรวจสอบคำขอของคุณฉันได้สร้าง 2 ตารางตามรูปแบบนี้:
- บันทึก 7.9 ล้านรายการที่แสดงถึงข้อมูลยอดเงินคงเหลือ
- ฟิลด์ตัวตนนับจาก 1 ถึง 7.9 ล้าน
- ฟิลด์ตัวเลขจัดกลุ่มเร็กคอร์ดในกลุ่มประมาณ 500k
ตารางแรกเรียกว่ามีดัชนีคลัสเตอร์ที่ไม่อยู่บนสนามheap
group
ตารางที่สองที่เรียกว่าclust
มีดัชนีคลัสเตอร์ในเขตข้อมูลตามลำดับที่เรียกว่าkey
และดัชนีที่ไม่ได้จัดกลุ่มบนฟิลด์group
การทดสอบดำเนินการบนโปรเซสเซอร์ I5 M540 ซึ่งมีคอร์ไฮเปอร์เธรด 2 คอร์หน่วยความจำ 4Gb และ Windows 64 บิต 7
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
Apr 2 2010 15:48:46
Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
อัปเดตเมื่อวันที่ 9 มีนาคม 2011 : ฉันได้ทำการวัดประสิทธิภาพที่ครอบคลุมมากขึ้นเป็นครั้งที่สองโดยการเรียกใช้รหัส. net และการบันทึกระยะเวลา, CPU, การอ่าน, การเขียนและการ RowCounts ใน SQL Server Profiler (CommandText ที่ใช้จะถูกกล่าวถึงในผลลัพธ์)
หมายเหตุ: CPU และ Duration แสดงเป็นมิลลิวินาที
- 1,000 ข้อความค้นหา
- การค้นหา CPU เป็นศูนย์จะไม่ถูกลบออกจากผลลัพธ์
- 0 แถวที่ได้รับผลกระทบจะถูกตัดออกจากผลลัพธ์
int[] idList = new int[] { 6816588, 7086702, 6498815 ... }; // 1000 values here.
using (var conn = new SqlConnection(@"Data Source=myserver;Initial Catalog=mydb;Integrated Security=SSPI;"))
{
conn.Open();
using (var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select * from heap where common_key between @id and @id+1000";
cmd.Parameters.Add("@id", SqlDbType.Int);
cmd.Prepare();
foreach (int id in idList)
{
cmd.Parameters[0].Value = id;
using (var reader = cmd.ExecuteReader())
{
int count = 0;
while (reader.Read())
{
count++;
}
Console.WriteLine(String.Format("key: {0} => {1} rows", id, count));
}
}
}
}
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
เลือกประสิทธิภาพ
ในการตรวจสอบหมายเลข performanc ฉันได้ทำการค้นหาต่อไปนี้หนึ่งครั้งบนตารางฮีปและหนึ่งครั้งบนตาราง clust:
select * from heap/clust where group between 5678910 and 5679410
select * from heap/clust where group between 6234567 and 6234967
select * from heap/clust where group between 6455429 and 6455729
select * from heap/clust where group between 6655429 and 6655729
select * from heap/clust where group between 6955429 and 6955729
select * from heap/clust where group between 7195542 and 7155729
ผลลัพธ์ของการวัดประสิทธิภาพนี้มีไว้สำหรับheap
:
rows reads CPU Elapsed
----- ----- ----- --------
1503 1510 31ms 309ms
401 405 15ms 283ms
2700 2709 0ms 472ms
0 3 0ms 30ms
2953 2962 32ms 257ms
0 0 0ms 0ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
cmd.CommandText = "select * from heap where group between @id and @id+1000";
- 721 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1001 69788 6368 -
Cpu 15 374 37 0.00754
Reads 1069 91459 7682 1.20155
Writes 0 0 0 0.00000
Duration 0.3716 282.4850 10.3672 0.00180
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
สำหรับตารางclust
ผลลัพธ์คือ:
rows reads CPU Elapsed
----- ----- ----- --------
1503 4827 31ms 327ms
401 1241 0ms 242ms
2700 8372 0ms 410ms
0 3 0ms 0ms
2953 9060 47ms 213ms
0 0 0ms 0ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
cmd.CommandText = "select * from clust where group between @id and @id+1000";
- 721 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1001 69788 6056 -
Cpu 15 468 38 0.00782
Reads 3194 227018 20457 3.37618
Writes 0 0 0 0.0
Duration 0.3949 159.6223 11.5699 0.00214
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
เลือกพร้อมกับเข้าร่วม
cmd.CommandText = "select * from heap/clust h join keys k on h.group = k.group where h.group between @id and @id+1000";
ผลลัพธ์ของการวัดประสิทธิภาพนี้มีไว้สำหรับheap
:
873 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1009 4170 1683 -
Cpu 15 47 18 0.01175
Reads 2145 5518 2867 1.79246
Writes 0 0 0 0.00000
Duration 0.8215 131.9583 1.9095 0.00123
ผลลัพธ์ของการวัดประสิทธิภาพนี้มีไว้สำหรับclust
:
865 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1000 4143 1685 -
Cpu 15 47 18 0.01193
Reads 5320 18690 8237 4.97813
Writes 0 0 0 0.00000
Duration 0.9699 20.3217 1.7934 0.00109
ปรับปรุงประสิทธิภาพ
คิวรีชุดที่สองคือข้อความสั่งการอัพเดต:
update heap/clust set amount = amount + 0 where group between 5678910 and 5679410
update heap/clust set amount = amount + 0 where group between 6234567 and 6234967
update heap/clust set amount = amount + 0 where group between 6455429 and 6455729
update heap/clust set amount = amount + 0 where group between 6655429 and 6655729
update heap/clust set amount = amount + 0 where group between 6955429 and 6955729
update heap/clust set amount = amount + 0 where group between 7195542 and 7155729
ผลลัพธ์ของการวัดประสิทธิภาพสำหรับheap
:
rows reads CPU Elapsed
----- ----- ----- --------
1503 3013 31ms 175ms
401 806 0ms 22ms
2700 5409 47ms 100ms
0 3 0ms 0ms
2953 5915 31ms 88ms
0 0 0ms 0ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
cmd.CommandText = "update heap set amount = amount + @id where group between @id and @id+1000";
- 811 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1001 69788 5598 811
Cpu 15 873 56 0.01199
Reads 2080 167593 11809 2.11217
Writes 0 1687 121 0.02170
Duration 0.6705 514.5347 17.2041 0.00344
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
ผลลัพธ์ของการวัดประสิทธิภาพสำหรับclust
:
rows reads CPU Elapsed
----- ----- ----- --------
1503 9126 16ms 35ms
401 2444 0ms 4ms
2700 16385 31ms 54ms
0 3 0ms 0ms
2953 17919 31ms 35ms
0 0 0ms 0ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
cmd.CommandText = "update clust set amount = amount + @id where group between @id and @id+1000";
- 853 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1001 69788 5420 -
Cpu 15 594 50 0.01073
Reads 6226 432237 33597 6.20450
Writes 0 1730 110 0.01971
Duration 0.9134 193.7685 8.2919 0.00155
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
ลบมาตรฐาน
ชุดการสืบค้นที่สามที่ฉันเรียกใช้เป็นคำสั่งลบ
delete heap/clust where group between 5678910 and 5679410
delete heap/clust where group between 6234567 and 6234967
delete heap/clust where group between 6455429 and 6455729
delete heap/clust where group between 6655429 and 6655729
delete heap/clust where group between 6955429 and 6955729
delete heap/clust where group between 7195542 and 7155729
ผลลัพธ์ของการวัดประสิทธิภาพนี้สำหรับheap
:
rows reads CPU Elapsed
----- ----- ----- --------
1503 10630 62ms 179ms
401 2838 0ms 26ms
2700 19077 47ms 87ms
0 4 0ms 0ms
2953 20865 62ms 196ms
0 4 0ms 9ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
cmd.CommandText = "delete heap where group between @id and @id+1000";
- 724 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 192 69788 4781 -
Cpu 15 499 45 0.01247
Reads 841 307958 20987 4.37880
Writes 2 1819 127 0.02648
Duration 0.3775 1534.3383 17.2412 0.00349
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
ผลลัพธ์ของการวัดประสิทธิภาพนี้สำหรับclust
:
rows reads CPU Elapsed
----- ----- ----- --------
1503 9228 16ms 55ms
401 3681 0ms 50ms
2700 24644 46ms 79ms
0 3 0ms 0ms
2953 26955 47ms 92ms
0 3 0ms 0ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
cmd.CommandText = "delete clust where group between @id and @id+1000";
- 751 แถวมี> 0 CPU และมีผลมากกว่า 0 แถว
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 144 69788 4648 -
Cpu 15 764 56 0.01538
Reads 989 458467 30207 6.48490
Writes 2 1830 127 0.02694
Duration 0.2938 2512.1968 24.3714 0.00555
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
เกณฑ์มาตรฐาน INSERT
ส่วนสุดท้ายของเกณฑ์มาตรฐานคือการดำเนินการคำสั่งแทรก
แทรกลงใน heap / clust (... ) ค่า (... ), (... ), (... ), (... ), (... ), (... )
ผลลัพธ์ของการวัดประสิทธิภาพนี้สำหรับheap
:
rows reads CPU Elapsed
----- ----- ----- --------
6 38 0ms 31ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
string str = @"insert into heap (group, currency, year, period, domain_id, mtdAmount, mtdAmount, ytdAmount, amount, ytd_restated, restated, auditDate, auditUser)
values";
for (int x = 0; x < 999; x++)
{
str += string.Format(@"(@id + {0}, 'EUR', 2012, 2, 0, 100, 100, 1000 + @id,1000, 1000,1000, current_timestamp, 'test'), ", x);
}
str += string.Format(@"(@id, 'CAD', 2012, 2, 0, 100, 100, 1000 + @id,1000, 1000,1000, current_timestamp, 'test') ", 1000);
cmd.CommandText = str;
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1000 1000 1000 -
Cpu 15 2138 25 0.02500
Reads 5212 7069 6328 6.32837
Writes 16 34 22 0.02222
Duration 1.6336 293.2132 4.4009 0.00440
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
ผลลัพธ์ของการวัดประสิทธิภาพนี้สำหรับclust
:
rows reads CPU Elapsed
----- ----- ----- --------
6 50 0ms 18ms
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
string str = @"insert into clust (group, currency, year, period, domain_id, mtdAmount, mtdAmount, ytdAmount, amount, ytd_restated, restated, auditDate, auditUser)
values";
for (int x = 0; x < 999; x++)
{
str += string.Format(@"(@id + {0}, 'EUR', 2012, 2, 0, 100, 100, 1000 + @id,1000, 1000,1000, current_timestamp, 'test'), ", x);
}
str += string.Format(@"(@id, 'CAD', 2012, 2, 0, 100, 100, 1000 + @id,1000, 1000,1000, current_timestamp, 'test') ", 1000);
cmd.CommandText = str;
Counter Minimum Maximum Average Weighted
--------- ------- ---------- ------- ---------
RowCounts 1000 1000 1000 -
Cpu 15 2403 21 0.02157
Reads 6810 8997 8412 8.41223
Writes 16 25 19 0.01942
Duration 1.5375 268.2571 6.1463 0.00614
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011
สรุปผลการวิจัย
แม้ว่าจะมีการอ่านแบบตรรกะเพิ่มเติมที่เกิดขึ้นเมื่อเข้าถึงตารางด้วยดัชนีที่คลัสเตอร์และดัชนีที่ไม่คลัสเตอร์ (ในขณะที่ใช้ดัชนีที่ไม่ใช่คลัสเตอร์) ผลการดำเนินงานคือ:
- คำสั่ง SELECT นั้นเปรียบได้
- คำสั่ง UPDATE เร็วขึ้นด้วยดัชนีคลัสเตอร์
- คำสั่ง DELETE นั้นเร็วขึ้นด้วยดัชนีคลัสเตอร์
- คำสั่ง INSERT นั้นเร็วขึ้นโดยมีดัชนีคลัสเตอร์อยู่
แน่นอนว่าเกณฑ์มาตรฐานของฉันนั้นมี จำกัด มากในตารางเฉพาะและมีชุดคำถามที่ จำกัด มาก แต่ฉันคิดว่าจากข้อมูลนี้เราสามารถเริ่มพูดแล้วว่ามันเป็นการดีกว่าการสร้างดัชนีกลุ่มบนโต๊ะของคุณ
อัพเดทเมื่อวันที่ 9 มีนาคม 2554 :
ดังที่เราเห็นจากผลลัพธ์ที่เพิ่มเข้ามาข้อสรุปของการทดสอบแบบ จำกัด นั้นไม่ถูกต้องในทุกกรณี
ตอนนี้ผลลัพธ์บ่งชี้ว่าเฉพาะข้อความสั่งที่ได้รับประโยชน์จากดัชนีคลัสเตอร์คือข้อความสั่งการปรับปรุง ข้อความอื่น ๆ จะช้าลงประมาณ 30% ในตารางที่มีดัชนีคลัสเตอร์
แผนภูมิเพิ่มเติมบางส่วนที่ฉันได้วางแผนระยะเวลาถ่วงน้ำหนักต่อการค้นหาสำหรับ heap vs clust
ในขณะที่คุณสามารถดูรายละเอียดผลการดำเนินงานสำหรับงบแทรกที่น่าสนใจมาก เดือยเกิดจากจุดข้อมูลน้อยซึ่งใช้เวลานานกว่าจะเสร็จสมบูรณ์
ในตอนท้ายของ Update เมื่อ 9 มีนาคม 2011