EXPLICIT : sử dụng nếu ứng dụng chỉ chấp nhận dữ liệu trong một định dạng được xác định trước, đây là tùy chọn có hiệu suất thấp nhất... Nội dung web từ SQL Server Sử dụng SQL Server
Trang 1NHÓM 7
SQL SERVER PERFORMANCE
1
CXZCZXCCCCCCCCCCCCC CCCCCCCCC
Võ Nguyễn Tuấn Vũ 1012543
Tô Trần Hiếu Lâm 1012210
Trang 29 Microsoft Access and SQL Server
10 SQL Server Backup and Restore
11 Transact-SQL SELECT Statement
Vinh
Vũ
Lâm
Trang 41 OPENXML
Chức năng OpenXML giúp nhập dữ liệu từ một file XML vào nhiều bảng trong SQL Server một cách hiệu quả nhất.
Khả năng ánh xạ một tài liệu XML đến một rowset tượng trưng trong một stored procedure có thể tối đa hóa hiệu suất khi việc insert dữ liệu được lặp đi lặp lại
Trang 52 Updategrams
Là phương thức dùng file xml để thêm, xóa, sửa dữ liệu trong 1 CSDL đã có sẵn trong Sql
Server.
Khi sử dụng sql:key-fields , phải thông báo khóa chính cho mọi bảng, nếu không, lệnh
WHERE sẽ bao gồm tất cả các thuộc tính của Element trước, làm giàm tốc độ tìm kiếm
Khi cập nhật hoặc xóa dữ liệu, chỉ liệt kê những thuộc tính được dùng tới, không liệt kê tất
cả
Khi cập nhật dữ liệu ở nhiều vùng dữ liệu không liên quan tới nhau, không nên gộp chung
trong một đoạn lệnh mà nên tách nhỏ ra
5
<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram"> <updg:sync>
<updg:before>
<States updg:id="1" Name="AK"/>
<States updg:id="2" Name="AR"/>
</updg:before>
<updg:after>
<States updg:id="1" Name="Alaska"/>
<States updg:id="2" Name="Arkansas"/>
Trang 63 FOR XML
Dùng để xuất dữ liệu từ SQL Server thành file XML.
Có 4 lựa chọn cơ bản : RAW, AUTO, PATH và EXPLICIT
RAW : hiệu suất tốt nhất, đặc biệt với lượng lớn dữ liệu Nhưng không phải tất cả các ứng dụng dựa trên XML có thể sử dụng
định dạng trả về loại RAW
AUTO : cung cấp hiệu suất tốt thứ 2, và rất nhiều các ứng dụng dựa trên XML có thể sử dụng lại định dạng này.
EXPLICIT : sử dụng nếu ứng dụng chỉ chấp nhận dữ liệu trong một định dạng được xác định trước, đây là tùy chọn có hiệu suất
thấp nhất
//RAW :
<row ID="1" Name=“Pen" />
<row ID=“2" Name=“Book" />
Trang 74 XPATH
Nếu sử dụng FOR XML EXPLICIT, trong một số trường hợp, có thể thay thế bằng truy vấn XPATH
XPATH thực hiện nhanh hơn, và có thể thay thế FOR XML EXPLICIT trong hầu hết các trường hợp.
7
SELECT x.value(N' / / / /@stepId', N'int') as StepID
, x.value(N' / /@id', N'int') as ComponentID
, x.value(N'@nom',N'nvarchar(100)') as Nom
, x.value(N'@valeur', N'nvarchar(100)') as Valeur
FROM@x.nodes(N'/xml/box/components/component/variables/variable') t(x)
XML SQL Server
Trang 85 XML Data options
Khi sử dụng FOR XML, không nên sử dụng tùy chọn XMLDATA
XMLDATA trả về dữ liệu XML schema không cần thiết Vì thế, bằng cách sử dụng tùy chọn này sẽ làm quá tải cho máy chủ và
kết nối mạng, làm giảm hiệu suất
Code ví dụ :
SELECT ID, Name FROM production WHERE ID=1 OR ID =2 FOR XML AUTO, XMLDATA
Trang 96 Nội dung web từ SQL Server
Sử dụng SQL Server và XML định kỳ tái tạo nội dung tĩnh định kỳ thay vì tự động tải nội dung mỗi khi nó cần từ SQL Server,
và lưu trữ các nội dung tĩnh này trên Web Server đối với dữ liệu không thay đổi thường xuyên.
Vì nếu một trang web được xem thường xuyên và mỗi lần đều phải chạy câu lệnh SELECT để lấy cùng một loại dữ liệu thì có
thể làm giảm đáng kể hiệu suất
9
Trang 10Composite Indexes
Chủ đề 2 :
Trang 111 Composite index là gì ?
Là index gồm từ 2 thuộc tính trở lên.
Cú pháp: CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX [idex1] ON [ Table ] (key1, key2, key3);
Giúp cho việc tìm kiếm dữ liệu nhanh hơn nhờ sắp xếp dữ liệu theo kiểu B-tree.
Trang 122 Không nên sử dụng
Nói chung, nên tránh sử dụng composite index Bởi composite index có xu hướng mở rộng, ngày càng lớn hơn, đòi hỏi nhiều
disk I / O để đọc nó, làm giảm hiệu suất.
Khó dự đoán trước Query Optimizer sẽ sử dụng index nào
Lý do chính rất nhiều composite index được tạo ra là do người lập trình mong muốn việc truy vấn sẽ sử dụng 1 trong các
composite index này làm tăng hiệu suất tìm kiếm.
Nhưng cách tốt nhất để làm tăng hiệu suất truy vấn là ở việc thiết kế dữ liệu tốt, không phải việc tạo nhiều index
Nếu bắt buộc phải tạo composite index, cố gắng để càng ít thuộc tính làm index càng tốt.
Trang 133 Composite index có ích khi nào ?
Query Optimizer có thể sẽ sử dụng composite index nếu trong truy vấn có thuộc tính nằm trong composite index.
Ví dụ : composite index ( A, B, C )
=> Truy vấn ( A=1,B=2,C=3 ), ( B=2, C=3 ), (B =2 ), (C=3) đều có thể sử dụng composite index trên bất kể tăng hay giảm hiệu suất.
Một composite index thông thường chỉ hữu ích cho một truy vấn nếu mệnh đề WHERE của truy vấn phù hợp với một hoặc nhiều thuộc tính tận cùng bên trái trong index
Ví dụ: composite index ( A, B, C )
=> truy vấn có lợi : ( A=1 ), ( A=1, B=2 ), ( A=1, B=2, C=3), ( A=1, B=2, C=3, D=4),
không có lợi: ( A=1, C=3), ( B=2, C=3 ), (B=2), …
13
Trang 165 Lưu ý về thuộc tính
Như bảng trên, ta thấy thuộc tính nào được khai báo trước sẽ được sắp xếp trước trong bảng index nên việc xếp thứ tự này là rất quan trọng.
Đặt thuộc tính được truy vấn nhiều nhất trước và các thuộc tính ít sử dụng hơn sau theo thứ tự từ trái qua phải.
Không đặt các thuộc tính ít sử dụng vào index.
Những thuộc tính thường xuyên phải update lại không nên có trong composite index.
Trang 176 Chia nhỏ index
Đôi khi, phân chia một composite index thành nhiều index đơn lại tốt hơn
Điều này là bởi vì chỉ có thuộc tính đầu tiên trong một composite index được lưu trữ cố định Và nếu thuộc tính đầu
tiên này không được truy vấn thường xuyên, nó sẽ không được Query Optimizer sử dụng
SQL Server có khả năng nối hai hay nhiều bảng index với nhau thành một composite index , tương tự việc ghép bảng,
việc này cung cấp cho những lợi ích tốt nhất của cả index đơn và composite index
* Nhưng không phải lúc nào điều này cũng đúng, Chỉ có thông qua thử nghiệm thực tế trong CSDL mới biết chắc chắn
được.
17
Index ( B )
Trang 187 : Primary key
Một index cũng được tự động tạo ra khi khai báo PRIMARY KEY hoặc UNIQUE Nếu có nhiều thuộc tính được tham gia, đó cũng là một composite
index.
Vì thế , phải luôn chú ý điều này khi quyết định tạo một composite index mới hay quyết định những thuộc tính có trong composite index để tránh những
index trùng nhau, và do mỗi index có độ ưu tiên khác nhau nên sẽ có những index không bao giờ được Query Optimizer sử dụng.
Trang 201 Sử dụng kiểu dữ liệu vừa đủ
Luôn chọn thuộc tính ở kích thước đủ để sử dụng , không chọn kiểu dữ liệu có kích thước lớn Việc này giúp :
Tiết kiệm dung lượng lưu trữ
Đọc và ghi dữ liệu nhanh hơn
Thực hiện sắp xếp nhanh hơn
Kiểu dữ liệu lớn Khi nào cần ? Kiểu dữ liệu nhỏ thay thế
Trang 212 VARCHAR hay CHAR ?
VARCHAR : nếu độ dài chuỗi không cố định, có thể lúc rất ngắn, lúc rất dài.
CHAR : nếu dộ dài chuỗi cố định.
Trang 223 INT thay cho CHAR/VARCHAR
Nếu lưu trữ một chuỗi số, nên dùng INTEGER thay VARCHAR hoặc CHAR
Kiểu dữ liệu số thường yêu cầu ít không gian hơn Điều này giúp giảm kích thước của các thuộc tính, và có thể tăng hiệu suất khi các thuộc
tính được tìm kiếm (mệnh đề WHERE), tham gia vào một thuộc tính khác hoặc sắp xếp
Tránh sử dụng FLOAT, REAL làm khóa chính, vì chúng tạo một số overhead không cần thiết làm ảnh hưởng tới hiệu suất của
hệ thống Sử dụng một trong các kiểu dữ liệu integer thay thế
Trang 235 NULL hay NOT NULL
Trong quá trình tạo bảng, luôn luôn chỉ định NULL hay NOT NULL cho mỗi thuộc tính.
Nếu không, thuộc tính sẽ mặc định NULL nếu sử dụng tùy chọn mặc định NULL DEFAULT ANSI và sẽ mặc định là NOT NULL nếu
không sử dụng tùy chọn ấy
Để đạt hiệu suất tốt nhất, và để giảm lỗi tiềm năng, thuộc tính lý tưởng nên được thiết lập để NOT NULL
Ví dụ : sử dụng của IS NULL trong mệnh đề WHERE làm cho truy vấn không thể sử dụng tốt index ( non- sargable )
Bad: Select WHERE isNull(FullName) = 'Ed Jones'
Fixed: Select WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))
23
Trang 24NYN: Chưa biết
TUN: Không biết
Nếu phải sử dụng NULLs, sử dụng kiểu dữ liệu có chiều dài biến thiên thay vì kiểu dữ liệu chiều dài cố định Kiểu dữ liệu có chiều dài biến thiên chỉ sử dụng một số lượng rất nhỏ không gian để lưu trữ một NULL.
Trang 257 Convert to variable data type
Nếu sử dụng CONVERT để chuyển đổi một giá trị thành một kiểu dữ liệu có chiều dài thay đổi, luôn luôn xác định độ dài của nó
Ví dụ kiểu VARCHAR, nếu không xác định chiều dài, SQL Server mặc định là 30 Nên xác định độ dài ngắn nhất có thể
Lưu ý : VARCHAR(30) : chiều dài tối đa là 30, chiều dài thực tế thay đổi và <= 30
• CHAR(30) : chiều dài thực tế luôn là 30
Ví dụ : CONVERT(VARCHAR(19),GETDATE());
25
Trang 268 Thuộc tính suy diễn
Nói chung, việc lưu trữ các thuộc tính có thể suy ra từ các thuộc tính khác không được khuyến khích bởi vì nó vi phạm dạng chuẩn của
CSDL
Tuy nhiên, đôi khi việc này đem lại hiệu quả cao nếu đó là dữ liệu được lặp đi lặp lại trong các truy vấn Giúp tránh được việc phải tính
toán nhiều lần cùng 1 phép tính.
Để quyết định có lưu trữ thuộc tính suy diễn hay không, bạn phải xác định xem thuộc tính đó có thường xuyên phải cập nhật lại không,
nếu có thì không nên sử dụng thuộc tính này Còn nếu những thuộc tính này hiếm khi thay đổi nhưng lại được truy vấn nhiều thì nên
sử dụng thuộc tính suy diễn
Trang 279 SQL_VARIANT
Không nên sử dụng kiểu dữ liệu SQL_VARIANT Kiểu này vừa làm giảm hiệu suất xử lý vừa gặp phải nhiều hạn chế khi sử dụng như :
Không thể làm khóa chính, khóa ngoại
Không thể dùng làm thuộc tính suy diễn
Tự động convert sang NVARCHAR(4000) nếu chuyển dữ liệu sang một CSDL khác
Không hỗ trợ lệnh LIKE trong truy vấn WHERE và một số lệnh khác
Trang 2810 Kiểu dữ liệu kích thước nhỏ làm khóa
Tránh sử dụng các kiểu dữ liệu có kích thước lớn làm khóa chính
Ví dụ, các kiểu dữ liệu DATETIME sử dụng 8 byte lưu trữ, trong khi kiểu dữ liệu INT chỉ chiếm 4 byte
Khóa càng có kích thước nhỏ, kích thước bảng và index càng nhỏ, giảm I/O overhead khi truy xuất khóa
Thử nghiệm thực tế cho thấy xử lý chuỗi định dạng Unicode chậm hơn non-Unicode.
Vì thế, không nên sử dụng chuỗi Unicode nếu không thật sự cần thiết
set @myvar = N’Central West College of TAFE’
set @myvar = ‘Central West College of TAFE’
Trang 29Transact-SQL General Tips
Chủ đề 4 :
29
Trang 301 Không truy vấn vô ích.
Không tạo mã, biến, hoặc các thông số vô ích Điều này nghe có vẻ hiển nhiên, nhưng thực tế điều này thường xuyên xày ra Ví dụ :
SELECT tên_thuộc tính FROM tên_bảng
WHERE năm_nhuận == false and ngày == ‘29/02’ ;
Trong thực tế, những truy vấn vô ích thường rất dài khiến cho người viết không dự đoán được trước kết quả trả về dẫn đến nhầm lẫn
Khi truy vấn này chạy, không có hàng nào được trả lại Nó chỉ lãng phí tài nguyên SQL Server và trong một số trường hợp còn thực sự gây ra lỗi SQL Server,
ngăn chặn các mã còn lại chạy
Trang 312 Comment
Khuyến khích việc sử dụng in-line comments và block comments, chúng sẽ không ảnh hưởng đến hiệu suất, và còn sẽ nâng cao
năng suất của bạn khi bạn phải trở lại và sửa đổi lại đoạn mã đó
31
Trang 323 Query cost limit
Sử dụng “query governor cost limit” để hạn chế thời gian một truy vấn có thể chạy Nếu chạy quá thời gian quy định, truy vấn
sẽ bị từ chối.
Thời gian quy định được tính bằng đơn vị second, tuy nhiên thời gian này được tính bởi Query Optimizer và không phải lúc nào
cũng giống thời gian thực tế Việc đặt giới hạn là bao nhiêu phải dựa vào kinh nghiệm sử dụng thực tế
Có 2 cách để đặt giới hạn :
exec sp_configure "query governor cost limit", <limit>
set query_governor_cost_limit <limit>
Trang 334 JOIN hay SUBQUERY
JOIN nhanh hơn SUBQUERY trong phần lớn trường hợp Tuy nhiên vẫn phải thử nghiệm thực tế trước khi đưa ra quyết định lựa
chọn giữa JOIN và SUBQUERY vì không phải lúc nào SUBQUERY cũng nhanh hơn
INNER JOIN department
ON employee.DepartmentID= department.DepartmentID
Trang 345 IDENTITY hay UNIQUE IDENTIFIER
Là 2 cách tạo khóa chính một cách tự động Ví dụ : MA int primay key identity(1,1)
IDENTITY được ưu tiên hơn UNIQUE IDENTIFIER vì 2 lý do :
Kích thước nhỏ hơn : ( kiểu int chiếm 4 byte ) , uniqueidentifier chiếm 16 byte
Khi tạo index, IDENTITY sẽ tạo theo thứ tự còn uniqueidentifier sẽ tạo một cách ngẫu nhiên, làm chậm hơn
Ví dụ unique identifier : B85E62C3-DC56-40C0-852A-49F759AC68FB.
Trang 356 Index cho temporary tables
Trong một vài trường hợp cần tạo temporary table, hãy cân nhắc việc tạo index cho bảng này.
Phần lớn các trường hợp thì không cần Nhưng nếu temporary table lớn thì lại cần Việc tạo index hợp lý cho các bảng này làm tăng hiệu suất tương tự
như tạo index cho các bảng chính.
Nhưng cách tốt nhất để quyết định tao hay không vẫn là thử nghiệm thực tế.
35
Thông thường, không nên dùng BREAK giữa vòng WHILE vì khó kiểm soát được điều kiện dừng nếu ở quá nhiều vị trí.
Nhưng trong SQL Server, việc BREAK giúp hạn chế bớt những truy vấn dư thừa và tăng tốc độ WHILE.
Trang 368 Hiển thị bool 0/1 thành No/Yes
Chỉ có những người hiểu về lập trình mới biết bool 0 tương đương với FALSE và 1 tương đương với TRUE Và đây là 1 cách để biến cách thể hiện bool thành chữ YES/NO
bool x ;
Công thức : SUBSTRING(‘YesNo’, 4 – 3 * x, 3)
x = 0 : SUBSTRING(‘YesNo’, 4, 3) = ‘NO’
x = 1 : SUBSTRING(‘YesNo’, 1, 3) = ‘YES’
* SUBSTRING ( expression ,start , length )
Việc này chỉ có ý nghĩa về mặt hiển thị, không có ý nghĩa về mặt lập trình
Trang 379 n-tier applications
Một trong những điểm lợi trong việc sử dụng SQL trong mô hình n-tier là SQL Server có thể gánh vác được phần xử lý dữ liệu
giúp các tier khác Việc này giúp giảm lượng dữ liệu phải di chuyển giữa các tier, làm cho cả ứng dụng nhanh hơn.
Nhưng SQL Server không tốt khi xử lý những tính toán phức tạp Ta phải giao công việc này cho các tier khác.
Sử dụng user-defined functions (UDFs) sẽ giải quyết được vấn đề này UDFs giúp chạy những tính toán phức tạp ngay trong SQL
Server SQL Server càng xử lý nhiều việc thì cả ứng dụng càng nhanh hơn
Tuy nhiên, việc tăng tốc một ứng dụng không chỉ đơn giản là giao mọi tính toán dữ liệu cho SQL Server mà đây chỉ là một cách
mà lập trình viên nên cân nhắc khi muốn tăng tốc ứng dụng.
37
Trang 3810 Kiểu dữ liệu table
SQL cung cấp kiểu dữ liệu “ table “.
Mục đích chính là để lưu trữ tạm một số bộ
Chỉ được dùng trong phạm vi được khai báo
Được sử dụng SELECT, INSERT, UPDATE, and DELETE như một bảng bình thường
Có thể dùng để thay thế temporary table Thường đem lại hiệu suất cao hơn :
Stored procedures nhanh hơn
Giảm thời gian lock, logging tài nguyên
CREATE TABLE Persons(
ID int, LastName varchar(255), FirstName varchar(255), )
INSERT INTO Person VALUES (1,’A’,B’)
CREATE TABLE #Person(
Id int, LastName varchar(255) )
INSERT INTO # Person( ID, LastName) SELECT ID, LastName
FROM dbo.Persons WHERE LastName = ‘A' table
temporary table
Trang 3911 Không lặp lại nhiều lần 1 phép tính
Đừng lặp đi lặp lại một hàm tính toán có cùng 1 kết quả.
Nếu phải sử dụng lại 1 kết quả, hãy lưu kết quả đó vào 1 biến và sử dụng lại biến này mỗi lần cần kết quả đó Việc này tiết kiệm
được tài nguyên của SQL.
Khi sử dụng thuộc tính identity làm khóa chính , SQL Server không đảm bảo được tính liên tục của nó nếu một số bộ bị delete.
Nếu không chấp nhận được điều này, có thể sử dụng trigger INSTEAD OF, nó giúp tránh được bất lợi này nhưng đương nhiên
sẽ tốn thêm chi phí thực hiện.
Tốt nhất là không nên xây dựng những thuật toán chạy tuần tự theo các khóa này Nếu có, phải chú ý vào những vấn đề có thể
xảy ra.
Trang 4013 BULK INSERT
Khi sử dụng BULK INSERT để nhập dữ liệu vào SQL Server, hãy cân nhắc sử dụng gợi ý TABLOCK
Việc này giúp SQL không running out of locks nếu khối lương dữ liệu import rất lớn và giảm xung đột khi lock.
Code ví dụ :
BULK INSERT EmployeeDB.dbo.Employees FROM 'C:\Data\EmployeeData_c.dat' WITH
( DATAFILETYPE = 'char', FIELDTERMINATOR = ',', ROWTERMINATOR = '\r\n' );