Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Thay thế con trỏ SQL bằng các giải pháp thay thế để tránh các vấn đề về hiệu suất

Trong bài viết này, chúng ta sẽ xem xét một số lựa chọn thay thế cho việc sử dụng con trỏ SQL có thể giúp tránh các vấn đề về hiệu suất do sử dụng con trỏ.

Trước khi thảo luận về các lựa chọn thay thế, hãy xem lại khái niệm chung về con trỏ SQL.

Tổng quan nhanh về con trỏ SQL

Con trỏ SQL chủ yếu được sử dụng khi các hoạt động dựa trên tập hợp không thể áp dụng và bạn được yêu cầu truy cập dữ liệu và thực hiện các thao tác từng hàng một thay vì áp dụng một thao tác dựa trên tập hợp đơn lẻ cho toàn bộ đối tượng (chẳng hạn như bảng hoặc một tập hợp bảng).

Định nghĩa đơn giản

Con trỏ SQL cung cấp quyền truy cập vào dữ liệu từng hàng một, do đó cung cấp cho bạn quyền kiểm soát trực tiếp từng hàng đối với tập kết quả.

Định nghĩa Microsoft

Theo tài liệu của Microsoft, câu lệnh Microsoft SQL Server tạo ra một tập hợp kết quả hoàn chỉnh, nhưng đôi khi tốt nhất là xử lý nó từng hàng một - có thể được thực hiện bằng cách mở một con trỏ trên tập kết quả.

Quy trình 5 bước sử dụng con trỏ

Quá trình sử dụng con trỏ SQL có thể được mô tả chung như sau:

  1. Khai báo con trỏ
  2. Mở Con trỏ
  3. Tìm nạp các hàng
  4. Đóng con trỏ
  5. Con trỏ Thỏa thuận phân bổ

Lưu ý quan trọng

Xin lưu ý rằng, theo Vaidehi Pandere, con trỏ là con trỏ chiếm bộ nhớ hệ thống của bạn - nếu không sẽ được dành cho các quy trình quan trọng khác. Đó là lý do tại sao duyệt qua một tập hợp kết quả lớn bằng cách sử dụng con trỏ thường không phải là ý tưởng tốt nhất - trừ khi có lý do chính đáng để làm điều đó.

Để biết thêm thông tin chi tiết về vấn đề này, vui lòng tham khảo bài viết của tôi Cách sử dụng con trỏ SQL cho các mục đích đặc biệt.

Ví dụ về con trỏ SQL

Đầu tiên, chúng ta sẽ xem xét một ví dụ về cách con trỏ SQL có thể được sử dụng để đổi tên từng đối tượng cơ sở dữ liệu.

Để tạo con trỏ SQL mà chúng ta cần, hãy thiết lập một cơ sở dữ liệu mẫu để chúng ta có thể chạy các tập lệnh của mình dựa trên nó.

Thiết lập cơ sở dữ liệu mẫu (UniversityV3)

Chạy tập lệnh sau để tạo và điền vào cơ sở dữ liệu mẫu UniversityV3 với hai bảng:

-- (1) Create UniversityV3 sample database

CREATE DATABASE UniversityV3;

GO

USE UniversityV3

-- (2) Create Course table

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES T WHERE T.TABLE_NAME='Course') 

DROP TABLE dbo.Course 

CREATE TABLE [dbo].[Course] (

    [CourseId] INT           IDENTITY (1, 1) NOT NULL,

    [Name]     VARCHAR (30)  NOT NULL,

    [Detail]   VARCHAR (200) NULL,

    CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED ([CourseId] ASC)

);

-- (3) Create Student table

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES T WHERE T.TABLE_NAME='Student') 

DROP TABLE dbo.Student 

CREATE TABLE [dbo].[Student] (

    [StudentId] INT           IDENTITY (1, 1) NOT NULL,

    [Name]      VARCHAR (30)  NULL,

    [Course]    VARCHAR (30)  NULL,

    [Marks]     INT           NULL,

    [ExamDate]  DATETIME2 (7) NULL,

    CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED ([StudentId] ASC)

);

-- (4) Populate Course table

SET IDENTITY_INSERT [dbo].[Course] ON

INSERT INTO [dbo].[Course] ([CourseId], [Name], [Detail]) VALUES (1, N'DevOps for Databases', N'This is about DevOps for Databases')

INSERT INTO [dbo].[Course] ([CourseId], [Name], [Detail]) VALUES (2, N'Power BI Fundamentals', N'This is about Power BI Fundamentals')

INSERT INTO [dbo].[Course] ([CourseId], [Name], [Detail]) VALUES (3, N'T-SQL Programming', N'About T-SQL Programming')

INSERT INTO [dbo].[Course] ([CourseId], [Name], [Detail]) VALUES (4, N'Tabular Data Modeling', N'This is about Tabular Data Modeling')

INSERT INTO [dbo].[Course] ([CourseId], [Name], [Detail]) VALUES (5, N'Analysis Services Fundamentals', N'This is about Analysis Services Fundamentals')

SET IDENTITY_INSERT [dbo].[Course] OFF



-- (5) Populate Student table

SET IDENTITY_INSERT [dbo].[Student] ON

INSERT INTO [dbo].[Student] ([StudentId], [Name], [Course], [Marks], [ExamDate]) VALUES (1, N'Asif', N'Database Management System', 80, N'2016-01-01 00:00:00')

INSERT INTO [dbo].[Student] ([StudentId], [Name], [Course], [Marks], [ExamDate]) VALUES (2, N'Peter', N'Database Management System', 85, N'2016-01-01 00:00:00')

INSERT INTO [dbo].[Student] ([StudentId], [Name], [Course], [Marks], [ExamDate]) VALUES (3, N'Sam', N'Database Management System', 85, N'2016-01-01 00:00:00')

INSERT INTO [dbo].[Student] ([StudentId], [Name], [Course], [Marks], [ExamDate]) VALUES (4, N'Adil', N'Database Management System', 85, N'2016-01-01 00:00:00')

INSERT INTO [dbo].[Student] ([StudentId], [Name], [Course], [Marks], [ExamDate]) VALUES (5, N'Naveed', N'Database Management System', 90, N'2016-01-01 00:00:00')

SET IDENTITY_INSERT [dbo].[Student] OFF

Tạo con trỏ SQL để đổi tên bảng (_Backup)

Bây giờ, hãy xem xét việc đáp ứng đặc điểm kỹ thuật sau bằng cách sử dụng con trỏ:

  1. Chúng tôi cần thêm ‘_Backup’ vào tên của tất cả các bảng hiện có trong cơ sở dữ liệu
  2. Bạn không nên đổi tên các bảng đã có ‘_Backup’ trong tên của chúng

Hãy tạo con trỏ SQL để đổi tên tất cả các bảng trong cơ sở dữ liệu mẫu bằng cách thêm ‘_Backup’ vào tên của từng bảng đồng thời đảm bảo rằng các bảng có chứa ‘_Backup’ trong tên của chúng sẽ không bị đổi tên lại bằng cách chạy mã sau:

-- Declaring the Student cursor to rename all tables by adding ‘_backup’ to their names and also making sure that all tables that are already named correctly will be skipped:

USE UniversityV3
GO

DECLARE @TableName VARCHAR(50) -- Existing table name
       ,@NewTableName VARCHAR(50) -- New table name

DECLARE Student_Cursor CURSOR FOR SELECT T.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T;

OPEN Student_Cursor

FETCH NEXT FROM Student_Cursor INTO @TableName

WHILE @@FETCH_STATUS = 0

BEGIN

IF RIGHT(@TableName,6)<>'Backup' -- If Backup table does not exist then rename the table

BEGIN

SET @[email protected]+'_Backup' -- Add _Backup to the table’s current name

EXEC sp_rename @TableName,@NewTableName -- Rename table as OLD table

END

ELSE

PRINT 'Backup table name already exists: '[email protected]

FETCH NEXT FROM Student_Cursor -- Get next row data into cursor and store it in variables

INTO @TableName

END

CLOSE Student_Cursor -- Close cursor locks on the rows

DEALLOCATE Student_Cursor -- Release cursor reference

Chạy tập lệnh đổi tên và xem kết quả

Bây giờ, nhấn F5 trong SSMS (SQL Server Management Studio) để chạy tập lệnh và xem kết quả:

Việc làm mới tên của bảng trong trình khám phá đối tượng SSMS cho thấy rõ ràng rằng chúng tôi đã thay đổi thành công chúng như được chỉ định.

Hãy chạy lại tập lệnh bằng cách nhấn F5 một lần nữa và xem kết quả:

Tạo con trỏ SQL để đặt lại _ Đặt tên sao lưu

Chúng tôi cũng cần tạo một tập lệnh sử dụng con trỏ SQL để hoàn nguyên tên của các bảng mà chúng tôi vừa thay đổi về các bảng ban đầu - chúng tôi sẽ thực hiện việc này bằng cách xóa ‘_Backup’ khỏi tên của chúng.

Tập lệnh dưới đây sẽ cho phép chúng tôi thực hiện điều đó:

-- Declare the Student cursor to reset tables names _backup to their original forms by removing ‘_backup’

USE UniversityV3

GO

DECLARE @TableName VARCHAR(50) -- Existing table name
       ,@NewTableName VARCHAR(50) -- New table name

DECLARE Student_Cursor CURSOR FOR SELECT T.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T;

OPEN Student_Cursor

FETCH NEXT FROM Student_Cursor INTO @TableName

WHILE @@FETCH_STATUS = 0

BEGIN

IF RIGHT(@TableName,6)='Backup' -- If Backup table name exists then reset (rename) it

BEGIN

SET @NewTableName=SUBSTRING(@TableName,1,LEN(@TableName)-7) -- Remove _Backup from the table name

EXEC sp_rename @TableName,@NewTableName -- Rename table 

END

ELSE

PRINT 'Backup table name already reset: '[email protected]

FETCH NEXT FROM Student_Cursor – Get the data of the next row into cursor and store it in variables

INTO @TableName

END

CLOSE Student_Cursor -- Close cursor locks on the rows

DEALLOCATE Student_Cursor -- Release cursor reference

Chạy tập lệnh đặt lại và xem kết quả

Chạy tập lệnh cho thấy rằng tên bảng đã được đặt lại thành công:

Đây là những ví dụ về một số tình huống trong đó khó tránh sử dụng con trỏ SQL do bản chất của yêu cầu. Tuy nhiên, vẫn có thể tìm được một cách tiếp cận thay thế.

Các lựa chọn thay thế con trỏ SQL

Có hai lựa chọn thay thế phổ biến nhất cho con trỏ SQL, vì vậy hãy xem xét chi tiết từng lựa chọn trong số chúng.

Thay thế 1:Biến bảng

Một trong những lựa chọn thay thế này là các biến bảng.

Các biến bảng, giống như bảng, có thể lưu trữ nhiều kết quả - nhưng có một số hạn chế. Theo tài liệu của Microsoft, biến bảng là một kiểu dữ liệu đặc biệt được sử dụng để lưu trữ tập hợp kết quả để xử lý sau này.

Tuy nhiên, hãy nhớ rằng các biến bảng được sử dụng tốt nhất với các tập dữ liệu nhỏ.

Các biến bảng có thể rất hiệu quả đối với các truy vấn quy mô nhỏ vì chúng hoạt động giống như các biến cục bộ và được dọn dẹp tự động khi ra khỏi phạm vi.

Chiến lược biến bảng:

Chúng tôi sẽ sử dụng các biến bảng thay vì con trỏ SQL để đổi tên tất cả các bảng từ cơ sở dữ liệu bằng cách làm theo các bước sau:

  1. Khai báo một biến bảng
  2. Lưu trữ tên và id bảng trong biến bảng mà chúng tôi đã khai báo
  3. Đặt bộ đếm thành 1 và nhận tổng số bản ghi từ biến bảng
  4. Sử dụng vòng lặp 'while' miễn là bộ đếm nhỏ hơn hoặc bằng tổng số bản ghi
  5. Bên trong vòng lặp "while", chúng tôi sẽ đổi tên từng bảng một miễn là chúng chưa được đổi tên và tăng bộ đếm cho mỗi bảng

Mã biến bảng:

Chạy tập lệnh SQL sau để tạo và sử dụng một biến bảng để đổi tên bảng:

-- Declare Student Table Variable to rename all tables by adding ‘_backup’ t their name and also making sure that already renamed tables are skipped

USE UniversityV3

GO

DECLARE @TableName VARCHAR(50) -- Existing table name
       ,@NewTableName VARCHAR(50) -- New table name

DECLARE @StudentTableVar TABLE -- Declaring a table variable to store tables names
(
TableId INT,

TableName VARCHAR(40))

INSERT INTO @StudentTableVar -- insert tables names into the table variable 

SELECT ROW_NUMBER() OVER(ORDER BY T.TABLE_NAME),T.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T

DECLARE @TotalRows INT=(SELECT COUNT(*) FROM @StudentTableVar),@i INT=1 -- Get total rows and set counter to 1

WHILE @i<[email protected] -- begin as long as i (counter) is less than or equal to the total number of records

BEGIN -- ‘While’ loop begins here

SELECT @TableName=TableName from @StudentTableVar WHERE [email protected]

IF RIGHT(@TableName,6)<>'Backup' -- If a Backup table does not exist, then rename the table

BEGIN

SET @[email protected]+'_Backup' -- Add _Backup to the table’s current name

EXEC sp_rename @TableName,@NewTableName -- Rename the table as OLD table

END

ELSE

PRINT 'Backup table name already exists: '[email protected]

SET @[email protected]+1

END -- 'While' loop ends here

Chạy Tập lệnh và Xem kết quả

Bây giờ, hãy thực thi tập lệnh và kiểm tra kết quả:

Phương án 2:Bảng Tạm thời

Chúng ta cũng có thể sử dụng các bảng tạm thời thay vì con trỏ SQL để lặp lại tập kết quả từng hàng một.

Bảng tạm thời đã được sử dụng trong một thời gian dài và cung cấp một cách tuyệt vời để thay thế con trỏ cho các tập dữ liệu lớn.

Cũng giống như các biến bảng, các bảng tạm thời có thể giữ tập hợp kết quả để chúng tôi có thể thực hiện các thao tác cần thiết bằng cách xử lý nó bằng một thuật toán lặp, chẳng hạn như vòng lặp ‘while’.

Chiến lược bảng tạm thời:

Chúng tôi sẽ sử dụng một bảng tạm thời để đổi tên tất cả các bảng trong cơ sở dữ liệu mẫu bằng cách làm theo các bước sau:

  1. Khai báo một bảng tạm thời
  2. Lưu trữ tên và id bảng trong bảng tạm thời mà chúng tôi vừa khai báo
  3. Đặt bộ đếm thành 1 và nhận tổng số bản ghi từ bảng tạm thời
  4. Sử dụng vòng lặp 'while' miễn là bộ đếm nhỏ hơn hoặc bằng tổng số bản ghi
  5. Trong vòng lặp ‘while’, hãy đổi tên từng bảng một miễn là chúng chưa được đổi tên và tăng bộ đếm cho từng bảng

Đặt lại bảng

Chúng tôi cần đặt lại tên của các bảng về dạng ban đầu bằng cách xóa '_Backup' khỏi tên của chúng, vì vậy vui lòng chạy lại tập lệnh đặt lại mà chúng tôi đã viết và sử dụng ở trên để chúng tôi có thể áp dụng một phương pháp đổi tên bảng khác.

Mã bảng tạm thời:

Chạy tập lệnh SQL sau để tạo và sử dụng bảng tạm thời để đổi tên tất cả các bảng trong cơ sở dữ liệu của chúng tôi:

-- Declare the Student Temporary Table to rename all tables by adding ‘_backup’ to their names while also making sure that already renamed tables are skipped

USE UniversityV3

GO

DECLARE @TableName VARCHAR(50) -- Existing table name
       ,@NewTableName VARCHAR(50) -- New table name

CREATE TABLE #Student -- Declaring a temporary table

(
TableId INT,
TableName VARCHAR(40)
)

INSERT INTO #Student -- insert tables names into the temporary table

SELECT ROW_NUMBER() OVER(ORDER BY T.TABLE_NAME),T.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T

DECLARE @TotalRows INT=(SELECT COUNT(*) FROM #Student),@i INT=1 -- Get the total amount of rows and set the counter to 1

WHILE @i<[email protected] -- begin as long as i (counter) is less than or equal to the total number of records

BEGIN -- ‘While’ loop begins here

SELECT @TableName=TableName from #Student WHERE [email protected]

IF RIGHT(@TableName,6)<>'Backup' -- If a Backup table does not exist, then rename the table

BEGIN

SET @[email protected]+'_Backup' -- Add ‘_Backup’ to the table’s current name

EXEC sp_rename @TableName,@NewTableName -- Rename the table as OLD table

END

ELSE

PRINT 'Backup table name already exists: '[email protected]

SET @[email protected]+1

END -- While loop ends here

DROP TABLE #Student

Chạy tập lệnh và kiểm tra đầu ra

Bây giờ, hãy thực thi tập lệnh để xem kết quả:

Việc cần làm

Bây giờ bạn đã quen với các lựa chọn thay thế cho con trỏ SQL - chẳng hạn như sử dụng các biến bảng và bảng tạm thời - hãy thử làm những việc sau để cảm thấy thoải mái khi áp dụng kiến ​​thức này vào thực tế:

  1. Tạo và đổi tên các chỉ mục của tất cả các bảng trong cơ sở dữ liệu mẫu - trước tiên thông qua Con trỏ, sau đó bằng cách sử dụng các phương pháp thay thế (biến bảng và bảng tạm thời)
  2. Hoàn nguyên tên của các bảng trong bài viết này về tên ban đầu của chúng bằng các phương pháp thay thế (bảng tạm thời và biến bảng)
  3. Bạn cũng có thể tham khảo (các) ví dụ đầu tiên trong bài viết của tôi Cách sử dụng Con trỏ SQL cho Mục đích Đặc biệt và thử điền các bảng có nhiều hàng và đo lường số liệu thống kê và thời gian cho các truy vấn để so sánh phương pháp con trỏ cơ bản với các lựa chọn thay thế

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chú ý đến các ước tính

  2. Tính giá trị trung vị bằng con trỏ động

  3. Cách tạo bảng từ truy vấn SQL

  4. Cách tạo một bảng từ một bảng khác trong SQL

  5. Mô hình dữ liệu nhà thông minh