Tối ưu SQL (phần 10): Lại là câu chuyện về GUID ID

Thủ đô xứ Đông Lào,  HÀ LỘI, ngày càng nóng bức quá đi 😐 Trở về căn nhà rộng rãi với hàng mét giường chiếu trải đầy trong phòng càng làm tôi thêm yêu cái mùa hè của xứ sở đầy nắng và gió này hơn :v

 

Chính vì vậy hôm nay ngẫu hứng kể lại 1 câu chuyện về tình yêu của tôi với GUID, câu chuyện này thì đã được tôi kể đi kể lại khá nhiều lần trong thiên sử blog này mà vẫn không hết chuyện.

Index là gì phong cách Pokemon GO

Bông tuyết cô độc

Tối ưu SQL (phần 7): Chuyện ngắn của ID

Haizz đó là 1 câu chuyện đẹp nhưng cũng sẽ lấy đi của bạn nhiều nước mắt đó. Giờ thì vào phần chính của câu chuyện nhé

Tôi đây, sau hơn 5 năm ra trường đã đi qua không ít hệ thống lớn nhỏ, nhúng tay vào hàng chục con DB và để lại những hậu quả không thể kể ra như Trịnh Xuân Thanh hay như Trầm Bê. Số lượng câu lệnh select trên các bảng nhiều như số tiền mà mấy thằng kia tham nhũng được :)) Nói thì to tát thế chứ chắc éo bằng được đâu 😐 Chúng nó có cả 43 nghìn tỉ cơ mà :(( mình chỉ cần số 3 không nghìn mà để lại chữ tỉ đã có thể vui nguyên 1 tuần rồi :(. Ấy là vì cái lẽ SELECT thì lắm nên việc ngồi nghịch ngợm những thứ liên quan đến ID hay key của các table trong CSDL thì chắc chả phải nói rồi. Đối với tôi bây giờ, khi không được động chạm vào nữa thì GUID nhiều nữa, GUID giờ trong tim tôi như “CÔ GÁI ĐẾN TỪ HÔM QUA”. Do đó tôi xin chia sẻ lại 1 số kỉ niệm đượm buồn của tôi đối với người con gái đấy để anh em hiểu được phần nào những thứ tôi đã từng trải qua để tối ưu CSDL khi chung chăn gối với người con gái này.

Đối với anh em làm việc với SQL Server thì GUID là 1 cái gì đó rất là tự nhiên. Mỗi lần chúng ta CREATE TABLE ra thì việc đặt tiên chúng ta nghĩ đến đó là SET PRIMARY KEY cho em ấy. Vâng chính là em ấy, người con gái tên GUID. Nếu anh em nào hay vọc vạch DB thì khi tạo primary key mặc định nó sẽ tạo INDEX trên trường này với loại INDEX là CLUSTERED. Và đó chính là vấn đề của tôi và em ấy GUID. Tôi đã không nói rõ với gia đình em ấy (MSSQL) để rồi gia đình em đã ép buộc cho em cái còng CLUSTERED oan nghiệt đó. Vừa tội cho em và cũng vừa tội cho tôi.

Như anh em mà biết thì rất rất nhiều bài viết khuyên về việc đặt CLUSTERED INDEX nên là 1 trường nhỏ bé sinh sinh, có tính duy nhất, nên là trường số. Những điều này chỉ để đáp ứng cho việc tối ưu cho tốc độ truy cập, bộ nhớ cũng như dung lượng lưu trữ của SQL. Chính vì thế nên GUID với độ dài 128 bit là 1 cái gì đó thật là quá xa vời so với lý tưởng chúng tôi đã đề ra (Điều này anh em có thể đọc về lợi ích của GUID cũng như tác hại của em ấy trong bài Bông tuyết cô độc)

Tôi xin nói lại 1 số thuật ngữ về PRIMARY KEY và CLUSTERED INDEX cho anh em thấu hiểu lại như sau

Bản chất của PRIMARY KEY là về mặt logic của CSDL nhằm giúp xác định 1 bản ghi là duy nhất trong 1 TABLE. Do để thích để nó là cái quái gì cũng được từ INT cho đến NVARCHAR

Còn đối với CLUSTERD INDEX thì mang tính chất về mặt lưu trữ vật lý. Chính vì thế mới cần nó nhỏ, ổn định như INT hay BIGINT. Do đó khi sử dụng GUID làm CLUSTERD INDEX thì sẽ tốn bộ nhớ hơn rất nhiều, mà đã nhiều thì càng tốn nhiều page trong SQL, càng lắm page thì truy vấn chậm là chả tránh được :3 Tuy vậy nếu ở trên hệ thống phân phối thì sử dụng GUID mang lại lợi ích tuyệt vời khi cần sync dữ liệu giữa các server hay các thiết bị :v Chính vì vậy việc cân nhắc giữa sử dụng GUID hay không cũng là 1 vấn đề đấy chứ :))

Ở đây có ít số liệu so sánh về mức độ lưu trữ dành cho INT và GUID anh em liếc mắt đưa tình nhìn xem

Với 1 bảng 1 triệu bản ghi, khi sử dụng INT so với GUID làm PRIMARY KEY và CLUSTER INDEX thì INT tốn tầm 3.8 MB còn GUID tận 15.5 MB 😐 Trên đó mà sử dụng thêm 6 trường NONCLUSTER INDEX thì 1 thằng là 23MB 1 thằng 92MB

Đã có rất nhiều bài viết tranh cãi về vấn đề có nên đặt GUID làm PRIMARY KEY hay không, cãi nhau gọi là um tí tỏi luôn. Tôi sẽ để link đây và không nói gì.

Nếu như vậy thì giải pháp thế nào để tối ưu cho cái này đấy :3 Theo như ngu ý của mình đưa ra cũng như tham khảo về 1 số cách làm của các bậc tiền bối trên INTERNET thì cách giải quyết đó là sử dụng thêm 1 cột INT làm CLUSTER INDEX thay cho trường PRIMARY KEY kiểu GUID. Làm như vậy thì sẽ nhàn hạ hơn cho DB tuy nhiên chắc code sẽ vất hơn đấy :v

Câu lệnh đơn giản chỉ có

CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
 MyINT INT IDENTITY(1,1) NOT NULL,
 .... add more columns as needed ...... )

ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)

CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)

Đấy chỉ có thế thôi. Anh em tự suy ngẫm tiếp về cuộc tình của mình với GUID đi nhé :v Giờ thì mình đi ngâm nước lạnh đây :v


Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s