[英]SQL Server hash function on table that represents the complete data on that table?
[英]Hash Table Data Structure in SQL Server
最近几天,我一直在阅读一本关于数据结构的电子书,坦率地说,很多事情已经从我的脑海中消失了。 只是回顾它们并试图再次澄清。 我正在浏览哈希表并再次熟悉它。 所以我知道并听说,SQL Server 在内部使用哈希表,stackoverflow.com 和 forums.asp.net 的许多线程询问有关在 SQL Server 中创建哈希表的问题,因为它存储临时数据。 因此,让我举一个我在使用临时表的存储过程中使用的示例:(避免它,它太长了。仅作为示例)
第一:
CREATE PROCEDURE [dbo].[Orders]
@OrderLine int
AS
BEGIN
DECLARE @t1 TABLE(Date1 date,
OrderID VARCHAR(MAX),
EmployeeName VARCHAR(MAX),
DeliveryDate date,
StoreName VARCHAR(MAX),
DeliveryAddress VARCHAR(MAX),
ItemName VARCHAR(MAX),
Quantity FLOAT)
INSERT INTO @t1(Date1, OrderID, EmployeeName, DeliveryDate, StoreName, DeliveryAddress, ItemName, Quantity)
(SELECT DISTINCT
CONVERT(VARCHAR(11), DemandOrder.POCreationDate, 6) AS DemandOrderDate,
DemandOrder.OrderID, EmployeeDetails.EmployeeName,
CONVERT(DATE, DemandOrder.DeliveryDate) AS ExpectedDeliveryDate,
StoreDetails.StoreName,
DemandOrder.DeliveryAddress, Item.ItemName,
DemandOrderLine.Quantity
FROM
DemandOrder
INNER JOIN
DemandOrderLine ON DemandOrder.OrderID = DemandOrderLine.OrderID
INNER JOIN
Item on DemandOrderLine.ItemID=Item.ItemID
INNER JOIN
EmployeeDetails ON EmployeeDetails.EmployeeID = DemandOrder.EmployeeID
INNER JOIN
StoreDetails ON DemandOrderLine.StoreID = StoreDetails.StoreID
WHERE
DemandOrderLine.OrderLine = @OrderLine)
DECLARE @t2 TABLE(Approvedby VARCHAR(MAX))
INSERT INTO @t2(Approvedby)
(SELECT EmployeeDetails.EmployeeName
FROM EmployeeDetails
INNER JOIN DemandOrderLine ON DemandOrderLine.ApprovedBy = EmployeeDetails.EmployeeID)
SELECT DISTINCT
CONVERT(VARCHAR(11), Date1, 6) AS Date,
OrderID, EmployeeName,
CONVERT(VARCHAR(11), DeliveryDate, 6) AS ExpectedDeliveryDate,
StoreName, Approvedby, DeliveryAddress,
ItemName, Quantity
FROM
@t1
CROSS JOIN
@t2
END
另一个,来自一个例子,它说在存储过程中,不能使用哈希表。 所以这里是:
第二:
CREATE PROCEDURE TempTable AS ---- It's actually not possible in SP
CREATE table #Color
(
Color varchar(10) PRIMARY key
)
INSERT INTO #color
SELECT 'Red'
UNION
SELECT 'White'
UNION
SELECT 'green'
UNION
SELECT 'Yellow'
UNION
SELECT 'blue'
DROP TABLE #color
CREATE table #Color
(
Color varchar(10) PRIMARY key
)
INSERT INTO #color
SELECT 'Red'
UNION
SELECT 'White'
UNION
SELECT 'green'
UNION
SELECT 'Yellow'
UNION
SELECT 'blue'
DROP TABLE #color
GO
所以我的问题是我可以说第一个是哈希表的一个例子,因为它使用临时表,如果不是,为什么我们不能在存储过程中使用它? 同样,如果它是内部创建的,为什么我们需要再次创建一个哈希表用于工作目的(虽然它有性能问题,只是想知道上面的例子是否适用于这个目的)。 谢谢。
注意:我上个月接受了一次采访并正在讨论它。 这就是为什么要确定我的观点是否正确。
我知道晚会晚了一点,但我认为没有人直接回答过您的原始问题。
第一个是表变量的示例,第二个是本地表的示例,两者均在tempdb中创建
它们之间的区别在于,表变量不是在内存中创建的,并且不能具有聚集索引。 同样,本地(哈希)表将一直停留到单个连接结束,而表变量仅可用于其声明所在的批处理。全局表(在其之前使用双哈希)将可用于所有连接并持续到使用它的所有连接均已关闭。
最后一件事,您不能在存储过程中使用该本地表的唯一原因是因为它使用了两次相同的名称,即使您已经使用了drop table,它也会首先基于批处理中的创建对其进行评估。 因此,它不会执行任何操作并且会抱怨它已经存在。
另请注意以下注意事项作为扩展注释,而不是单独的答案:
[1] SQL Server具有INNER HASH JOIN
( INNER HASH JOIN
)和查询提示( OPTION (HASH JOIN)
, OPTION(HAS GROUP')
),以便实施此类物理联接或分组。
[2]在内部,SQL Server使用哈希表作为锁标识符。 请参见未记录的功能%% lockres %%(请参阅http://www.sqlskills.com/blogs/paul/investigating-locking-and-deadlocking-with-lockres/ )。
USE tempdb
GO
CREATE TABLE dbo.Documents (
ID INT IDENTITY(1,1) PRIMARY KEY,
DocDate DATE NOT NULL,
Content VARCHAR(8000) NOT NULL
);
CREATE INDEX IX_Documents_DocDate
ON dbo.Documents (DocDate)
GO
INSERT dbo.Documents (DocDate, Content)
VALUES
('2016-01-01', REPLICATE(CONVERT(VARCHAR(MAX), 'A'), 4000)),
('2016-02-02', REPLICATE(CONVERT(VARCHAR(MAX), 'B'), 5000)),
('2016-03-04', REPLICATE(CONVERT(VARCHAR(MAX), 'C'), 6000));
GO
SELECT ID, DocDate, %%lockres%% AS record_lock_hash
FROM dbo.Documents WITH(INDEX=1) -- Clustered index
GO
/*
ID DocDate record_lock_hash
----------- ---------- --------------------------------
1 2016-01-01 (8194443284a0)
2 2016-02-02 (61a06abd401c)
3 2016-03-04 (98ec012aa510)
*/
GO
SELECT ID, DocDate, %%lockres%% AS record_lock_hash
FROM dbo.Documents WITH(INDEX=IX_Documents_DocDate) -- Non-Clustered index
GO
/*
ID DocDate record_lock_hash
----------- ---------- --------------------------------
1 2016-01-01 (417e1de8c3fb)
2 2016-02-02 (6aede25aab61)
3 2016-03-04 (e701c6578164)
*/
GO
[3]作为数据库开发人员,我使用“哈希表”(使用哈希函数定义的计算列)来索引大文本(或blob),因此:
ALTER TABLE dbo.Documents
ADD ContentHash AS CHECKSUM(HASHBYTES('sha256', Content)) /*PERSISTED*/ -- Computed column
GO
SET ANSI_NULLS, QUOTED_IDENTIFIER ON
GO
SET ANSI_WARNINGS, ANSI_PADDING, ARITHABORT, CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT OFF
GO
CREATE INDEX IX_Documents_ContentHash
ON dbo.Documents (ContentHash)
--INCLUDE (Content)
GO
DECLARE @ParamContent VARCHAR(8000) = REPLICATE(CONVERT(VARCHAR(MAX), 'B'), 5000)
DECLARE @ParamHash INT = CHECKSUM(HASHBYTES('sha256', @ParamContent))
SELECT d.ID, d.Content
FROM dbo.Documents d WITH(FORCESEEK)
WHERE d.ContentHash = @ParamHash -- Index Seek Predicate (Fast/optimized if there is an index on ContentHash computed column)
AND d.Content = @ParamContent -- [Simple / non-indexed] Predicate (Slow)
GO
注意: 索引计算列时请注意 (请参阅SET
tings的要求)。
DECLARE @SEPERATOR as VARCHAR(1)
DECLARE @SP INT
DECLARE @VALUE VARCHAR(MAX)
SET @SEPERATOR = ','
CREATE TABLE #TempCode (id int NOT NULL)
/**this Region For Storing SiteCode**/
WHILE PATINDEX('%' + @SEPERATOR + '%', @Code ) <> 0
BEGIN
SELECT @SP = PATINDEX('%' + @SEPERATOR + '%' ,@Code)
SELECT @VALUE = LEFT(@Code , @SP - 1)
SELECT @Code = STUFF(Code, 1, @SP, '')
INSERT INTO #TempCode (id) VALUES (@VALUE)
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.