การใช้ varchar (MAX) กับ TEXT บน SQL Server


196

ฉันเพิ่งอ่านว่าVARCHAR(MAX)ประเภทข้อมูล (ซึ่งสามารถเก็บได้ใกล้เคียงกับ 2GB ของข้อมูลถ่าน) คือการแทนที่ที่แนะนำสำหรับTEXTประเภทข้อมูลใน SQL Server 2005 และรุ่นถัดไปของ SQL Server

หากฉันต้องการค้นหาสตริงใด ๆ ในคอลัมน์การดำเนินการใดที่เร็วกว่า

  1. ใช้ส่วนLIKEคำสั่งกับVARCHAR(MAX)คอลัมน์หรือไม่

    WHERE COL1 LIKE '%search string%'

  2. ใช้TEXTคอลัมน์และใส่ดัชนีข้อความ / แคตตาล็อกแบบเต็มในคอลัมน์นี้แล้วค้นหาโดยใช้CONTAINSข้อ?

    WHERE CONTAINS (Col1, 'MyToken')


1
โพสต์นี้มีประโยชน์เช่นกัน: stackoverflow.com/questions/564755/…
Jake

25
การกล่าวถึงที่สำคัญที่สุดในโพสต์นั้นคือลิงค์ไปยังเอกสาร MSDN ที่แสดงว่าTEXTและNTEXT(และIMAGE) เลิกใช้แล้ว
Brian

คำตอบ:


316

ประเภทจะเปลี่ยนสำหรับVARCHAR(MAX) TEXTความแตกต่างพื้นฐานคือTEXTประเภทจะเก็บข้อมูลใน blob เสมอในขณะที่VARCHAR(MAX)ชนิดจะพยายามเก็บข้อมูลโดยตรงในแถวเว้นแต่จะเกินข้อ จำกัด 8k และ ณ จุดนั้นจะเก็บไว้ในหยด

การใช้คำสั่ง LIKE เหมือนกันระหว่างสองประเภทข้อมูล ฟังก์ชั่นเพิ่มเติมVARCHAR(MAX)ให้คุณคือมันยังสามารถใช้กับ=และGROUP BYเป็นVARCHARคอลัมน์อื่น ๆได้ อย่างไรก็ตามหากคุณมีข้อมูลจำนวนมากคุณจะมีปัญหาด้านประสิทธิภาพอย่างมากโดยใช้วิธีการเหล่านี้

ในเรื่องเกี่ยวกับว่าคุณควรจะใช้LIKEในการค้นหาหรือหากคุณควรใช้การจัดทำดัชนีข้อความแบบเต็มCONTAINSและ คำถามนี้เป็นคำถามเดียวกันโดยไม่คำนึงถึงหรือVARCHAR(MAX)TEXT

ถ้าคุณกำลังค้นหาข้อความจำนวนมากและประสิทธิภาพการทำงานเป็นกุญแจสำคัญแล้วคุณควรใช้ดัชนีข้อความแบบเต็ม

LIKE ง่ายต่อการใช้งานและมักจะเหมาะสำหรับข้อมูลจำนวนเล็กน้อย แต่มีประสิทธิภาพต่ำมากกับข้อมูลขนาดใหญ่เนื่องจากไม่สามารถใช้ดัชนีได้


12
ฉันไม่รู้ว่ามันจะเก็บไว้ในหน้าเพจที่ 8k และจะออกจากหน้าถ้ามีขนาดใหญ่กว่า เด็ดมาก
Brain2000

3
บรรทัดสุดท้ายของคุณผิดบางส่วน LIKE ไม่สามารถใช้ดัชนีเฉพาะถ้าสัญลักษณ์ตัวแทนอยู่ที่จุดเริ่มต้นของสตริงที่ค้นหา
SouravA

1
จะไม่มีปัญหาในการเปลี่ยนแปลงเขตข้อมูลจากข้อความเป็น varchar (สูงสุด) จากตารางที่มีข้อมูลอยู่หรือไม่?
user1531040

17

สำหรับข้อความที่มีขนาดใหญ่ที่ดัชนีข้อความเต็มรูปแบบเป็นมากได้เร็วขึ้น แต่คุณสามารถสร้างดัชนีข้อความแบบเต็มได้ varchar(max)เช่นกัน


16

คุณไม่สามารถค้นหาช่องข้อความโดยไม่แปลงจากข้อความเป็น varchar

declare @table table (a text)
insert into @table values ('a')
insert into @table values ('a')
insert into @table values ('b')
insert into @table values ('c')
insert into @table values ('d')


select *
from @table
where a ='a'

สิ่งนี้ทำให้เกิดข้อผิดพลาด:

The data types text and varchar are incompatible in the equal to operator.

สิ่งนี้ไม่ได้:

declare @table table (a varchar(max))

ที่น่าสนใจLIKEยังคงใช้งานได้เช่น

where a like '%a%'

11
+1 เพียงเพื่อพูด downvote สุ่ม! ทำให้ฉันเป็นบ้าเมื่อมีคนลงคะแนนให้ฉันและไม่มีความเห็นพวกเขาจำเป็นต้องมีชีวิตจริงๆ
Tom Stickel

3
เหตุผลที่เขาได้ลงคะแนนคือจากสิ่งที่ฉันจำได้จากสิ่งที่ฉันต้องทำไม่ใช่ข้อโต้แย้งที่ถูกต้องที่จะนำมาเมื่อตอบคำถามทางเทคนิค คิดเกี่ยวกับผู้คน (เช่นฉันในขณะนี้) พยายามที่จะยืนยันว่าทำไมเราควรใช้varchar(n)หรือเพื่อtextให้ได้คำตอบนี้ คุณคิดว่าในสภาพแวดล้อมที่เป็นมืออาชีพการโต้เถียงกับข้อความที่คลุมเครือจะช่วยแก้ปัญหาได้หรือไม่? โพสต์ทั้งหมดบน StackOverflow นั้นมีผู้คนหลายพันคนให้คุณเห็น
Anwar

3
@Zeratops ฮ่า ๆ คำตอบนี้คือ 6 ปีฉันค่อนข้างสีเขียวดังนั้นเมื่อฉันเขียนมัน ฉันล้างถ้อยคำให้ละเอียดมากขึ้น
DForck42

9
  • คำจำกัดความพื้นฐาน

TEXTและVarChar(MAX)เป็นประเภทข้อมูลอักขระความยาวแปรผันขนาดใหญ่แบบ Non-Unicode ซึ่งสามารถจัดเก็บอักขระได้สูงสุด 2147483647 อักขระที่ไม่ใช่ Unicode (เช่นความจุสูงสุดคือ: 2GB)

  • จะใช้อันไหนดี?

ตามลิงค์ MSDN Microsoft ขอแนะนำให้หลีกเลี่ยงการใช้ประเภทข้อมูล Text และจะถูกลบออกใน SQL Server รุ่นต่อไปในอนาคต Varchar (Max) เป็นชนิดข้อมูลที่แนะนำสำหรับการจัดเก็บค่าสตริงขนาดใหญ่แทนประเภทข้อมูล Text

  • พื้นที่เก็บข้อมูลแบบ In-Row หรือ Out-of-Row

ข้อมูลของTextคอลัมน์ประเภทถูกจัดเก็บไว้นอกแถวในหน้าข้อมูล LOB ที่แยกต่างหาก แถวในหน้าข้อมูลตารางจะมีตัวชี้ 16 ไบต์ไปยังหน้าข้อมูล LOB ที่มีข้อมูลจริงอยู่ ในขณะที่ข้อมูลของVarchar(max)คอลัมน์ประเภทจะถูกเก็บไว้ในแถวถ้าน้อยกว่าหรือเท่ากับ 8000 ไบต์ หากค่าคอลัมน์ Varchar (สูงสุด) ข้าม 8000 ไบต์ค่าคอลัมน์ Varchar (สูงสุด) จะถูกเก็บไว้ในหน้าข้อมูล LOB แยกต่างหากและแถวจะมีตัวชี้ 16 ไบต์ไปยังหน้าข้อมูล LOB ที่มีข้อมูลจริงอยู่ ดังนั้นIn-RowVarchar (สูงสุด) จึงเหมาะสำหรับการค้นหาและดึงข้อมูล

  • ฟังก์ชันที่รองรับ / ไม่รองรับ

ฟังก์ชันสตริงตัวดำเนินการหรือโครงสร้างที่ไม่ทำงานในคอลัมน์ชนิดข้อความบางส่วน แต่ทำงานในคอลัมน์ประเภท VarChar (สูงสุด)

  1. = เท่ากับ Operator บนคอลัมน์ประเภท VarChar (สูงสุด)
  2. จัดกลุ่มตามข้อในคอลัมน์ประเภท VarChar (สูงสุด)

    • ข้อควรพิจารณาของระบบ IO

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

แต่ถ้าค่าส่วนใหญ่ที่เก็บไว้ในคอลัมน์ประเภท VarChar (สูงสุด) มีขนาดเล็กพอที่จะเก็บในแถว จากนั้นการดึงข้อมูลที่ไม่รวมคอลัมน์ LOB ต้องมีจำนวนหน้าข้อมูลมากขึ้นในการอ่านเนื่องจากค่าคอลัมน์ LOB ถูกเก็บไว้ในแถวในหน้าข้อมูลเดียวกันกับที่เก็บค่าคอลัมน์ที่ไม่ใช่ LOB แต่ถ้าแบบสอบถามแบบใช้เลือกข้อมูลมีคอลัมน์ LOB จะต้องใช้จำนวนหน้าน้อยลงในการอ่านข้อมูลเมื่อเทียบกับคอลัมน์ประเภทข้อความ

ข้อสรุป

ใช้VarChar(MAX)ชนิดข้อมูลแทนTEXTเพื่อประสิทธิภาพที่ดี

แหล่ง


5

หากใช้MS Access (โดยเฉพาะรุ่นที่เก่ากว่าเช่นปี 2003) คุณจะถูกบังคับให้ใช้TEXTประเภทข้อมูลบน SQL Server เนื่องจาก MS Access ไม่ได้รับการยอมรับnvarchar(MAX)ว่าเป็นเขตข้อมูล Memo ใน Access ในขณะที่TEXTได้รับการยอมรับว่าเป็นเขตข้อมูล Memo

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