Views จะปรับให้เหมาะสมเมื่อฉันเพิ่มส่วนคำสั่ง WHERE กับพวกเขาหรือไม่


28

มันสร้างความแตกต่างหรือไม่ถ้าคุณกรองมุมมองภายในหรือภายนอกมุมมอง

ตัวอย่างเช่นมีข้อแตกต่างระหว่างสองข้อความค้นหานี้หรือไม่

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

หรือ

SELECT Id
FROM MyView
WHERE SomeColumn = 1

และMyViewถูกกำหนดให้เป็น

SELECT Id, SomeColumn
FROM MyTable

และเป็นคำตอบที่แตกต่างกันหรือไม่หากตารางต้นฉบับตั้งอยู่บนเซิร์ฟเวอร์ที่เชื่อมโยง

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


1
ทำไมคุณถึงใช้มุมมองหากคุณมีเพียงหนึ่งตารางในนั้น
HLGEM

3
@HLGEM ความปลอดภัยหรือไม่
JNK

2
@HLGEM UNION ALLดูจริงมีคำสั่งหลายที่หลายฐานข้อมูลบนเซิร์ฟเวอร์ที่แตกต่างกันและร่วมกับพวกเขาทั้งหมดโดย การใช้ View นั้นง่ายกว่าการเขียนคำสั่ง UNION ใหม่ทุกครั้งที่ต้องการข้อมูล
Rachel

นอกจากนี้โปรดดูstackoverflow.com/a/6654525/27535
gbn

1
@Datagod ฉันจะจำไว้ขอบคุณ :) ในกรณีนี้มีแอพขนาดเล็กพอสมควรที่รวบรวมข้อมูลจากเซิร์ฟเวอร์จำนวนมากทำการคำนวณบางอย่างและแยกรายงานออกเป็นส่วน ๆ มันมีฐานข้อมูลของตัวเองเพราะการคำนวณบางอย่างค่อนข้างใช้ทรัพยากรอย่างหนักและฉันต้องการแยกมันออกจากทุกอย่าง
Rachel

คำตอบ:


12

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

ตอนนี้ขึ้นอยู่กับชนิดข้อมูลและการเลือกของMyColumnหากคุณต้องการสร้างดัชนีกรองบนตารางฐาน (เมื่อคุณย้ายไปยัง SQL Server 2008+) คุณอาจได้รับประสิทธิภาพที่ดีขึ้น แต่สิ่งนี้จะไม่แตกต่างกันในมุมมอง หรือไม่


3
คำถามอะไรที่ถามว่าทำไมแบบสอบถามที่มีส่วนwhereคำสั่งนอกมุมมองนั้นใช้เวลานานกว่าตอนที่อยู่ในมุมมอง
Rachel

1
หากมุมมองไม่ได้มีไว้สำหรับการทำงานพวกเขามีไว้สำหรับโครงสร้างเท่านั้น
profimedica

1
@profimedica สามารถสร้างมุมมองที่จัดทำดัชนีด้วยเหตุผลด้านประสิทธิภาพ (เช่นการจัดเก็บผลลัพธ์ตัวกลางเช่นมวลรวมแทนที่จะคำนวณมุมมองขณะรันไทม์) หากมุมมองไม่ได้เกิดขึ้นจริงก็สามารถทำได้ด้วยเหตุผลหลายประการ: DRY (การเข้าร่วมทั่วไปหรือตัวกรองที่ดำเนินการในแบบสอบถามที่แตกต่างกันจำนวนมาก) ความปลอดภัยการทำให้งงงวยการทำให้เข้าใจง่ายของสคีมา
Aaron Bertrand

5

นี่เป็นเพียงตัวอย่างด่วนที่แสดงว่าไม่ควรมีความแตกต่าง ฐานข้อมูลเป็นAdventureWorksฐานข้อมูล

คำจำกัดความของมุมมองทั้งสอง:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

ต่อไปนี้เป็นคำถามแรกที่มีส่วนWHEREคำสั่งรวมอยู่ในนิยามมุมมอง:

select *
from person.vContactWhere

นี่คือแผนการดำเนินการ:

ป้อนคำอธิบายรูปภาพที่นี่

และแบบสอบถามที่สองที่มีส่วนWHEREคำสั่งไม่ได้อยู่ในคำนิยามมุมมอง แต่ในSELECTแบบสอบถาม:

select *
from person.vContactNoWhere
where ContactID = 24

นี่คือแผนการดำเนินการ:

ป้อนคำอธิบายรูปภาพที่นี่

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


1
คำถามอะไรที่ถามว่าทำไมแบบสอบถามที่มีส่วนwhereคำสั่งนอกมุมมองนั้นใช้เวลานานกว่าตอนที่อยู่ในมุมมอง
Rachel

1
@ ราเชลฉันคิดว่า gbn อธิบายได้ค่อนข้างดีในโพสต์ของเขาและบทความที่เขาชี้ไป ฉันไม่รู้จะใส่ยังไง
Thomas Stringer

ฉันเชื่อมโยงสิ่งนั้นเพราะในกรณีนั้นแผนการดำเนินการไม่เหมือนกันซึ่งแตกต่างจากคำตอบของคุณ
Rachel

1
@Rachel ปัญหาในตัวอย่างที่เป็นหายกฎการเปลี่ยนแปลง มันไม่ได้ใช้กับมุมมองเท่านั้น แต่ยังรวมถึง CTE และนิพจน์ตารางอื่น ๆ ในกรณีทั่วไปมันไม่ถูกต้องที่จะผลักภาคลงไปในการแสดงออกของตารางที่มีฟังก์ชั่นการจัดอันดับที่จะเปลี่ยนผล เหตุผลที่มันเป็นสิ่งที่ถูกต้องในกรณีนี้เป็นเพราะข้อพอดีWhere PARTITION BYSQL Server 2008 ดูเหมือนว่าจะมีกฎใหม่SelOnSeqPrjในการรับรู้กรณีนี้โดยเฉพาะ
Martin Smith


2

จากสิ่งที่ ฉันกำลัง อ่าน SQL จะใช้มุมมองมาตรฐานเช่นแบบสอบถามย่อยเมื่อพิจารณาแผนการดำเนินการ

ดังนั้นการใช้แบบสอบถามตัวอย่างของฉัน

SELECT Id
FROM MyView
WHERE SomeColumn = 1

โดยMyViewนิยามว่าเป็น

SELECT Id, SomeColumn
FROM MyTable

มันควรสร้างแผนการดำเนินการเช่นเดียวกับ

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

แต่แผนการดำเนินการนี้อาจแตกต่างจากสิ่งที่จะสร้างขึ้นด้วย

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

ฉันไม่แน่ใจว่าคำตอบนี้จะเหมือนกันสำหรับมุมมองที่จัดทำดัชนีหรือไม่


ฉันไม่คิดว่ามันเป็นการแทนที่ข้อความที่ชัดเจนเช่นนั้น
แอรอนเบอร์ทรานด์ด์

@AaronBertrand คุณอาจพูดถูก ฉันไม่รู้ว่าจริง ๆ แล้ว ... ฉันกำลังเรียนรู้เมื่อฉันไป :) ข้อสันนิษฐานนั้นขึ้นอยู่กับสิ่งอื่น ๆ ที่ฉันได้อ่านเกี่ยวกับมุมมองของมาโคร ฉันแก้ไขคำถามเล็กน้อยเพื่อระบุว่าฉันอ้างถึงมุมมองมาตรฐานไม่ใช่มุมมองที่จัดทำดัชนี
Rachel

@Rachel - การทดแทนเกิดขึ้นกับต้นไม้ algebrized ที่ระดับต้นฉบับ
Martin Smith

@MartinSmith Hrrmm นั่นไม่ใช่สิ่งที่ฉันพูด? ว่าแผนปฏิบัติการควรจะเหมือนกันไม่ใช่ว่าข้อความจะเหมือนกันหรือไม่? ฉันไม่แน่ใจว่าฉันเข้าใจ "ต้นไม้ algebrized"
Rachel

มันเป็นเพียงการตอบสนองต่อความคิดเห็นของคุณใน Q ซึ่งบอกว่ามัน "แทรกข้อความ View ในแบบสอบถามของคุณ" และความคิดเห็นของ Aaron ด้านบน ข้อมูลบางอย่างเกี่ยวกับการแยกวิเคราะห์ / รวบรวมขั้นตอนที่นี่ ที่จริงคำตอบของคุณไม่พูดถึงการทดแทนข้อความเช่นกัน ไม่ว่าจะเป็นความแตกต่างที่คุ้มค่ากับการทำ ไม่แน่ใจ! แต่ฉันเดาว่ามันอธิบายว่าทำไมจึงsp_refreshviewจำเป็นซึ่งแนวคิดการแทนที่ข้อความจะไม่
Martin Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.