คำถามติดแท็ก optimization

ในบริบทของฐานข้อมูลการปรับให้เหมาะสมหมายถึงกระบวนการของเครื่องมือเพิ่มประสิทธิภาพคิวรีที่เลือกแผนการดำเนินการทางกายภาพที่มีประสิทธิภาพ

1
กฎใดที่กำหนดเมื่อ SQL Server ใช้ CTE เป็น "รั้วการปรับให้เหมาะสม"
ในขณะที่กลับมา Brent Ozar เผยแพร่โพสต์รายละเอียดบางส่วนของความแตกต่างระหว่าง SQL Server และ PostgreSQL: ความแตกต่างที่สำคัญสองประการระหว่าง SQL Server กับ PostgreSQL จุดแรก (“ CTE เป็นรั้วการเพิ่มประสิทธิภาพ”) จับตาของฉันเพราะเห็นได้ชัดว่าในตัวอย่างที่มีให้ SQL Server รวม CTE และแบบสอบถามหลักเข้าด้วยกันและปรับให้เป็นแบบสอบถามเดียว (ตรงข้ามกับพฤติกรรมตรงข้ามใน PostgreSQL) อย่างไรก็ตามพฤติกรรมนี้ดูเหมือนจะตรงกันข้ามกับตัวอย่างที่ฉันเห็นในบล็อกและคลาสฝึกอบรมอื่น ๆ ที่ SQL Server ใช้ CTE เป็นรั้วการปรับให้เหมาะสมซึ่งช่วยให้ใช้ดัชนีได้ดีขึ้นประสิทธิภาพที่ดีขึ้นเป็นต้นตัวอย่างเช่น วิธีที่ดีกว่าในการเลือกดาว ดังนั้นดูเหมือนว่า SQL Server จะ "ให้เกียรติ" CTE เป็นกรอบการเพิ่มประสิทธิภาพบางครั้ง มีทรัพยากรที่ดีใดบ้างที่บันทึกรายการเฉพาะของกรณีที่ทราบซึ่ง SQL Server จะให้เกียรติ CTE อย่างน่าเชื่อถือเป็นรั้วการเพิ่มประสิทธิภาพ (หรือพฤติกรรมที่ตรงกันข้าม)

2
ทำไมจึงเร็วกว่านี้และปลอดภัยที่จะใช้หรือไม่ (ที่ตัวอักษรตัวแรกอยู่ที่ไหนในตัวอักษร)
เรื่องย่อสั้น ๆ เรากำลังอัปเดตผู้คนกลุ่มเล็ก ๆ ด้วยค่านิยมจากกลุ่มคนที่มีขนาดใหญ่มาก ในการทดสอบล่าสุดการอัพเดทนี้ใช้เวลาประมาณ 5 นาทีในการรัน เราพบสิ่งที่ดูเหมือนว่าการปรับให้เหมาะสมที่สุดที่เป็นไปได้ซึ่งดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์แบบ! แบบสอบถามเดียวกันนี้ทำงานในเวลาน้อยกว่า 2 นาทีและสร้างผลลัพธ์เดียวกันอย่างสมบูรณ์แบบ นี่คือแบบสอบถาม บรรทัดสุดท้ายถูกเพิ่มเป็น "การเพิ่มประสิทธิภาพ" ทำไมเวลาค้นหาที่ลดลงอย่างมาก พวกเราขาดอะไรบางอย่าง? สิ่งนี้นำไปสู่ปัญหาในอนาคตได้หรือไม่? UPDATE smallTbl SET smallTbl.importantValue = largeTbl.importantValue FROM smallTableOfPeople smallTbl JOIN largeTableOfPeople largeTbl ON largeTbl.birth_date = smallTbl.birthDate AND DIFFERENCE(TRIM(smallTbl.last_name),TRIM(largeTbl.last_name)) = 4 AND DIFFERENCE(TRIM(smallTbl.first_name),TRIM(largeTbl.first_name)) = 4 WHERE smallTbl.importantValue IS NULL -- The following line …

2
การคำนวณปริมาณสต็อคตามบันทึกการเปลี่ยนแปลง
ลองนึกภาพว่าคุณมีโครงสร้างตารางต่อไปนี้: LogId | ProductId | FromPositionId | ToPositionId | Date | Quantity ----------------------------------------------------------------------------------- 1 | 123 | 0 | 10002 | 2018-01-01 08:10:22 | 5 2 | 123 | 0 | 10003 | 2018-01-03 15:15:10 | 9 3 | 123 | 10002 | 10004 | 2018-01-07 21:08:56 | 3 4 …

1
B-Tree จะปรับสมดุลในระหว่างการลบข้อมูลจากตาราง SQL Server ที่มีดัชนีคลัสเตอร์หรือไม่?
ฉันมีตารางในฐานข้อมูล SQL Server ที่มีดัชนีคลัสเตอร์ในคีย์หลัก ตารางมี 1 ล้านแถว หากฉันลบแถว 10K ออกจากตารางดัชนีจะถูกปรับโครงสร้างใหม่ในระหว่างการดำเนินการลบหรือไม่? การดำเนินการลบเป็นส่วนหนึ่งของกระบวนงานที่เก็บไว้ ในแต่ละครั้งลูกค้ามากกว่าหนึ่งรายสามารถเรียกใช้งานโพรซีเดอร์ที่เก็บไว้ได้อย่างไรก็ตามการรันแต่ละรายการจะลบชุดของแถวเอง (ระบุโดยคีย์หลัก) ฉันกำลังปิดกั้นคีย์ล็อค (ประเภท U) เมื่อลูกค้าหลายรายดำเนินการตามขั้นตอน ล็อคบล็อคเป็นของแถวจากตารางเดียวกันและไม่ได้เป็นส่วนหนึ่งของการทำธุรกรรมใด ๆ ที่ทำงานพร้อมกัน ไม่ควรมีการบล็อกใด ๆ เนื่องจากการรันแต่ละครั้งพยายามลบมันเป็นชุดของแถว การยกระดับการล็อคไม่ได้เกิดขึ้นเนื่องจากปิดอยู่ ฉันสงสัยว่าการดำเนินการลบจะต้องทำให้ดัชนีมีการปรับสมดุลและดังนั้นในระหว่างกระบวนการปรับโครงสร้างจึงสามารถใช้การล็อคปุ่มบนแถวใดก็ได้ของตาราง ฉันขอขอบคุณความคิดเห็นใด ๆ เกี่ยวกับเรื่องนี้

2
วิธีการกำหนดค่าใช้จ่าย / ผลประโยชน์ของการเพิ่มดัชนี?
ตามที่Craig Ringer : แม้ว่าโดยทั่วไปจะเป็นความคิดที่ดีที่จะสร้างดัชนีใน (หรือรวมถึง) คอลัมน์คีย์ต่างประเทศอ้างอิงของคุณ แต่ก็ไม่จำเป็น แต่ละดัชนีคุณเพิ่มช้า DML การดำเนินงานลดลงเล็กน้อยเพื่อให้คุณจ่ายค่าใช้จ่ายการปฏิบัติงานในทุกINSERT, หรือUPDATE DELETEหากดัชนีนั้นไม่ค่อยได้ใช้อาจไม่คุ้มค่า คุณจะทราบได้อย่างไรว่าผลประโยชน์ของการเพิ่มดัชนีเกินกว่าราคาหรือไม่ คุณโปรไฟล์หน่วยทดสอบก่อน / หลังเพิ่มดัชนีและตรวจสอบเพื่อเพิ่มประสิทธิภาพโดยรวมหรือไม่? หรือมีวิธีที่ดีกว่า

1
ฉันจะ 'บอกใบ้' ความสำคัญของ CTE แบบเรียกซ้ำได้อย่างไร
ฉันใช้ CTE แบบเรียกซ้ำต่อไปนี้เป็นตัวอย่างขั้นต่ำ แต่โดยทั่วไปเครื่องมือเพิ่มประสิทธิภาพจะต้องใช้ค่าเริ่มต้นที่เป็น 'เดา' สำหรับ CTE แบบเรียกซ้ำ with recursive w(n) as ( select 1 union all select n+1 from w where n<5 ) select * from w; /* n --- 1 2 3 4 5 */ explain analyze with recursive w(n) as ( select 1 union all select n+1 …

1
การแปลงประเภทในการแสดงออกอาจส่งผลกระทบต่อ "CardinalityEstimate" ในตัวเลือกแผนแบบสอบถาม?
ฉันรักษาฐานข้อมูลเก็บถาวรที่เก็บข้อมูลประวัติในมุมมองที่แบ่งพาร์ติชัน คอลัมน์แบ่งเป็นวันที่และเวลา แต่ละตารางใต้มุมมองจะเก็บข้อมูลหนึ่งเดือน เรา จำกัด กิจกรรมในแต่ละตารางด้วยข้อ จำกัด การตรวจสอบในคอลัมน์วันที่และเวลา สิ่งนี้อนุญาตให้เครื่องมือเพิ่มประสิทธิภาพ จำกัด ตารางที่ค้นหาการสืบค้นที่กรองในคอลัมน์วันที่และเวลาของเหตุการณ์ ชื่อของข้อ จำกัด การตรวจสอบถูกสร้างขึ้นโดย SQL Server ดังนั้นจึงยากที่จะรู้ว่าสิ่งที่พวกเขาทำโดยดูที่ชื่อของพวกเขา ฉันต้องการชื่อข้อ จำกัด ที่จะมีรูปแบบ 'CK_TableName_Partition' ฉันสามารถสร้างสคริปต์การเปลี่ยนชื่อโดยใช้แบบสอบถามนี้และคัดลอกข้อมูลจากคอลัมน์ sql_text WHERE clause ตรงกับการตรวจสอบข้อ จำกัด ที่ชื่อดูเหมือนว่าถูกสร้างขึ้นโดย SQL Server: SELECT checks.name AS check_name, tabs.name AS table_name, skemas.name AS schema_name, cols.name AS column_name, N' EXECUTE sys.sp_rename @objname = N''' + …

3
การบันทึกทุกการเปลี่ยนแปลงของแถวในฐานข้อมูลนั้นถูกเก็บไว้อย่างไร?
ในโครงการที่ฉันกำลังดำเนินการการเปลี่ยนแปลงแถวในบางตารางของฐานข้อมูลต้องถูกติดตามเพื่อการตรวจสอบเพิ่มเติมหรือย้อนกลับ มันจะต้องง่ายต่อการค้นหาผู้ที่แก้ไขแถวจากที่อยู่ IP และเวลาใดและสามารถกู้คืนเวอร์ชันก่อนหน้าได้ สิ่งที่คล้ายกันนั้นใช้โดย Stack Exchange เมื่อฉันเปลี่ยนคำถามของคนอื่นมันเป็นไปได้ที่จะพบว่าฉันเปลี่ยนมันและย้อนกลับการเปลี่ยนแปลง เทคนิคทั่วไปที่ใช้ในการจัดเก็บการเปลี่ยนแปลงทุกอย่างกับวัตถุในฐานข้อมูลคืออะไรเนื่องจากสคีมาปัจจุบันของฉันมีคุณสมบัติเหมือนกัน (ด้านล่าง) ส่วนใหญ่ที่เป็นแอปทางธุรกิจโดยเฉลี่ย วัตถุที่มีขนาดค่อนข้างเล็ก: อาจจะมีบางnvarchar(1000)ตัวอย่างเช่น แต่ไม่ blobs ใหญ่ของข้อมูลไบนารีหนึ่งนี้ถูกเก็บไว้โดยตรงบนดิสก์และเข้าถึงได้โดยตรงและไม่ผ่าน Microsoft SQL filestream, โหลดฐานข้อมูลค่อนข้างต่ำและฐานข้อมูลทั้งหมดได้รับการจัดการโดยเครื่องเสมือนหนึ่งเครื่องบนเซิร์ฟเวอร์ การเข้าถึงเวอร์ชันก่อนหน้าไม่จำเป็นต้องรวดเร็วเท่ากับการเข้าถึงเวอร์ชันล่าสุด แต่ยังต้องเป็นเวอร์ชันล่าสุดและไม่ช้าเกินไป² <TL-DR> ฉันคิดเกี่ยวกับกรณีต่อไปนี้ แต่ฉันไม่มีประสบการณ์จริงกับสถานการณ์เหล่านั้นดังนั้นฉันจะได้ยินความคิดเห็นของผู้อื่น: เก็บทุกอย่างไว้ในตารางเดียวกันโดยแยกแถวตาม ID และรุ่น IMO มันโง่มากและจะเจ็บไม่ช้าก็เร็วในระดับประสิทธิภาพ ด้วยวิธีนี้มันเป็นไปไม่ได้ที่จะตั้งระดับความปลอดภัยที่แตกต่างกันไปเป็นไอเท็มล่าสุดและการติดตามเวอร์ชั่น ในที่สุดทุกคำถามจะมีความซับซ้อนในการเขียน ที่จริงแล้วในการเข้าถึงข้อมูลที่ทันสมัยฉันจะถูกบังคับให้จัดกลุ่มทุกอย่างด้วยรหัสและดึงข้อมูลในแต่ละกลุ่มเวอร์ชันสุดท้าย เก็บเวอร์ชันล่าสุดไว้ในตารางเดียวและในทุก ๆ การเปลี่ยนแปลงให้คัดลอกเวอร์ชันที่ล้าสมัยไปยังตารางอื่นในสคีมาอื่น ข้อบกพร่องคือทุกครั้งที่เราเก็บทุกค่าแม้ว่ามันจะไม่เปลี่ยนแปลง การตั้งค่าการเปลี่ยนแปลงที่จะnullไม่ได้เป็นวิธีการแก้ปัญหาตั้งแต่ฉันยังต้องติดตามเมื่อค่าที่มีการเปลี่ยนแปลงไปหรือจากnullnull เก็บเวอร์ชันล่าสุดไว้ในตารางเดียวและรายการคุณสมบัติที่เปลี่ยนแปลงด้วยค่าก่อนหน้าในตารางอื่น นี้ดูเหมือนว่ามีสองข้อบกพร่อง: binary(max)หนึ่งที่สำคัญที่สุดคือว่าวิธีเดียวที่จะเรียงลำดับประเภทที่แตกต่างกันของค่าก่อนหน้านี้ในคอลัมน์เดียวกันคือการมี อย่างที่สองคือฉันเชื่อว่ามันจะยากกว่าที่จะใช้โครงสร้างดังกล่าวเมื่อแสดงเวอร์ชันก่อนหน้าแก่ผู้ใช้ ทำสิ่งเดียวกันกับในสองประเด็นก่อนหน้านี้ แต่เก็บรุ่นไว้ในฐานข้อมูลแยกต่างหาก ประสิทธิภาพอาจเป็นเรื่องที่น่าสนใจเพื่อหลีกเลี่ยงการชะลอการเข้าถึงเวอร์ชันล่าสุดโดยให้มีเวอร์ชันก่อนหน้าในฐานข้อมูลเดียวกัน ยังฉันเชื่อว่ามันเป็นการเพิ่มประสิทธิภาพก่อนวัยอันควรและจะต้องทำก็ต่อเมื่อมีหลักฐานที่แสดงว่ารุ่นเก่าและรุ่นล่าสุดในฐานข้อมูลเดียวกันเป็นคอขวด </ TL-DR> ¹ตัวอย่างเช่นจะไม่สามารถจัดเก็บการเปลี่ยนแปลงลงในไฟล์บันทึกได้เนื่องจากจะทำเพื่อบันทึก HTTP …

2
PostgreSQL เพิ่มประสิทธิภาพการเพิ่มคอลัมน์ด้วยค่าเริ่มต้นที่ไม่ใช่ค่า NULL หรือไม่
เมื่อเพิ่มNOT NULLคอลัมน์ที่มีDEFAULTค่า - PostgreSQL ปรับการดำเนินการนี้ให้เหมาะสมหรือไม่ ในกรณีที่ตารางมี n แถว, คอลัมน์เปลี่ยนแปลงที่ไม่ได้รับการปรับให้เหมาะสมจะทำให้การเขียน n ของค่าเริ่มต้น - ซึ่งอาจเป็นเรื่องที่เจ็บปวดอย่างมาก ด้วยการปรับให้เหมาะสมฐานข้อมูลจะสร้างคอลัมน์ใหม่ทันทีเก็บเพียงหนึ่งสำเนาของค่าเริ่มต้นซึ่งจะถูกส่งกลับเมื่อไม่พบค่าที่ไม่ใช่ค่าเริ่มต้นสำหรับคอลัมน์นั้นในโครงสร้างข้อมูลดัชนีที่เหมาะสม ตัวอย่างเช่นOracle 11g มีการเพิ่มประสิทธิภาพเช่นนั้น

3
เข้าร่วมด้วยตนเองในคีย์หลัก
พิจารณาคำถามนี้ซึ่งประกอบด้วยการรวมNตัวเอง: select t1.* from [Table] as t1 join [Table] as t2 on t1.Id = t2.Id -- ... join [Table] as tN on t1.Id = tN.Id มันสร้างแผนการดำเนินการด้วยการสแกนดัชนี N คลัสเตอร์และการรวม N-1 ผสาน สุจริตฉันไม่เห็นเหตุผลใด ๆ ที่จะไม่เพิ่มประสิทธิภาพการเข้าร่วมทั้งหมดและทำการสแกนดัชนีแบบคลัสเตอร์เดียวเพียงครั้งเดียวนั่นคือปรับการค้นหาดั้งเดิมให้เหมาะกับสิ่งนี้: select t1.* from [Table] as t1 คำถาม เหตุใดการรวมจึงไม่ได้รับการปรับให้เหมาะสม มันไม่ถูกต้องทางคณิตศาสตร์หรือไม่ที่จะบอกว่าการเข้าร่วมทุกครั้งไม่เปลี่ยนชุดผลลัพธ์ ทดสอบเมื่อ: เซิร์ฟเวอร์ต้นทางรุ่น: SQL Server 2014 (12.0.4213) Source Database …

1
คอลัมน์ที่คำนวณอย่างต่อเนื่องทำให้เกิดการสแกน
การแปลงคอลัมน์ปกติเป็นคอลัมน์ที่คำนวณแล้วยังคงเป็นสาเหตุให้แบบสอบถามนี้ไม่สามารถค้นหาดัชนีได้ ทำไม? ทดสอบกับ SQL Server หลายเวอร์ชันรวมถึง 2016 SP1 CU1 Repros ด้วยคอลัมน์ที่คำนวณ ด้วยคอลัมน์ปกติ ปัญหาคือมี,table1col7 ตารางและแบบสอบถามเป็นต้นฉบับบางส่วน (และง่าย) ของต้นฉบับ ฉันทราบว่าคำถามอาจถูกเขียนใหม่แตกต่างกันและด้วยเหตุผลบางอย่างหลีกเลี่ยงปัญหา แต่เราจำเป็นต้องหลีกเลี่ยงการสัมผัสรหัสและคำถามที่ว่าทำไมtable1ไม่สามารถค้นหายังคงยืนอยู่ ดังที่ Paul White แสดงให้เห็น (ขอบคุณ!) การแสวงหานั้นจะเกิดขึ้นหากถูกบังคับดังนั้นคำถามคือ: ทำไมเครื่องมือเพิ่มประสิทธิภาพจึงไม่ได้ถูกเลือกโดยเครื่องมือเพิ่มประสิทธิภาพและไม่ว่าเราจะสามารถทำสิ่งที่แตกต่างออกไป รหัส? เพื่อชี้แจงส่วนที่มีปัญหานี่คือการสแกนที่เกี่ยวข้องในแผนการดำเนินการที่ไม่ดี:

3
แผนการดำเนินการไม่ได้ใช้ INDEX แต่ใช้การสแกนตาราง
ฉันรู้ว่าเมื่อใช้ดัชนีหรือการสแกนตาราง SQL Server จะใช้สถิติเพื่อดูว่าอันไหนดีกว่า ฉันมีตารางที่มี 20 ล้านแถว ฉันมีดัชนีใน (SnapshotKey, การวัด) และแบบสอบถามนี้: select Measure, SnapshotKey, MeasureBand from t1 where Measure = 'FinanceFICOScore' group by Measure, SnapshotKey, MeasureBand แบบสอบถามส่งคืนแถว 500k ดังนั้นแบบสอบถามจึงเลือกเพียง 2.5% ของแถวของตาราง คำถามคือทำไม SQL Server ไม่ใช้ดัชนี nonclustered ฉันมีและใช้การสแกนตารางแทน? มีการอัพเดทสถิติ ดีที่จะพูดถึงว่าประสิทธิภาพของแบบสอบถามนั้นดี สแกนตาราง ดัชนีบังคับ โครงสร้างตาราง / ดัชนี CREATE TABLE [t1]( [SnapshotKey] [int] NOT …

5
การสแกนแม้ว่าฉันคาดหวังการค้นหา
ฉันต้องการเพิ่มประสิทธิภาพของSELECTคำสั่ง แต่ SQL Server จะทำการสแกนดัชนีแทนการค้นหา นี่คือแบบสอบถามที่แน่นอนอยู่ในขั้นตอนการจัดเก็บ: CREATE PROCEDURE dbo.something @Status INT = NULL, @IsUserGotAnActiveDirectoryUser BIT = NULL AS SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName], [Profession], [BirthDate], [HireDate], [ActiveDirectoryUser] FROM Employee WHERE (@Status IS NULL OR [Status] = @Status) AND ( @IsUserGotAnActiveDirectoryUser IS NULL OR ( @IsUserGotAnActiveDirectoryUser IS NOT NULL …

1
เซสชันที่ถูกบล็อกรอด้วย PAGELATCH_ * รอประเภทหรือไม่
แก้ไข: เหตุใดการรายงานเซสชันถูกบล็อก แต่รอด้วยPAGELATCH_*และไม่LCK_M_เกี่ยวข้องกับประเภทการรอ ก่อนหน้านี้ฉันสันนิษฐานว่าเซิร์ฟเวอร์ SQL จะรายงานเฉพาะเซสชันการบล็อกในคอลัมน์บล็อค_session_Idเท่านั้น PAGELATCH_*หากการประชุมที่ถูกบล็อกกำลังรอล็อคตรรกะและไม่ได้อะไรอย่างอื่นเช่น

2
MySQL: ลบ…ใน .. ใน () เทียบกับลบ .. จาก .. เข้าร่วมและล็อคตารางเมื่อลบด้วยการเลือกย่อย
คำเตือน: โปรดแก้ตัวความรู้ของฉันเกี่ยวกับฐานข้อมูลภายใน นี่มันไป: เราเรียกใช้แอปพลิเคชั่น (ไม่ได้เขียนโดยเรา) ซึ่งมีปัญหาประสิทธิภาพการทำงานใหญ่ในงานล้างข้อมูลเป็นระยะในฐานข้อมูล แบบสอบถามมีลักษณะดังนี้: delete from VARIABLE_SUBSTITUTION where BUILDRESULTSUMMARY_ID in ( select BUILDRESULTSUMMARY_ID from BUILDRESULTSUMMARY where BUILDRESULTSUMMARY.BUILD_KEY = "BAM-1"); ตรงไปตรงมา SQL ที่อ่านง่ายและมาตรฐาน แต่น่าเสียดายที่ช้ามาก การอธิบายเคียวรีแสดงว่าไม่ได้ใช้ดัชนีที่VARIABLE_SUBSTITUTION.BUILDRESULTSUMMARY_IDมีอยู่: mysql> explain delete from VARIABLE_SUBSTITUTION where BUILDRESULTSUMMARY_ID in ( -> select BUILDRESULTSUMMARY_ID from BUILDRESULTSUMMARY -> where BUILDRESULTSUMMARY.BUILD_KEY = "BAM-1"); | id | select_type …

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