我目前正在使用C#构建网络搜寻器。若要将尚未爬网的URL排队,请使用SQL Server。它的运行速度非常快,但是随着时间的流逝它开始变得很大,这减慢了我的存储过程。

CREATE TABLE PriorityQueue
(
ID int IDENTITY(0,1) PRIMARY KEY,
absolute_url varchar (400),
depth int,
priorty int,
domain_host varchar (255),
);

CREATE INDEX queueItem ON PriorityQueue(absolute_url);
CREATE INDEX queueHost ON PriorityQueue(domain_host);


这是我用于队列的表。优先级数字从1到5,其中1为最高优先级。如您所见,我还将在下面对存储过程使用索引。

将新项目添加到队列的过程:

DROP PROCEDURE IF EXISTS dbo.Enqueue
GO
CREATE PROCEDURE dbo.Enqueue(@absolute_url varchar(255), @depth int, @priorty int, @host varchar(255))
AS
BEGIN
    INSERT INTO [WebshopCrawler].[dbo].[PriorityQueue] (absolute_url, depth, priorty, domain_host) VALUES (@absolute_url, @depth, @priorty, @host);
END
GO


获得最高优先级的项目的步骤:

DROP PROCEDURE IF EXISTS dbo.Dequeue
GO
CREATE PROCEDURE dbo.Dequeue
AS
BEGIN
    SELECT top 1 absolute_url, depth, priorty
    FROM [WebshopCrawler].[dbo].[PriorityQueue]
    WHERE priorty = (SELECT MIN(priorty) FROM [WebshopCrawler].[dbo].[PriorityQueue])
END
GO


随着数据量的增加,这一步确实变慢了。

删除出队项目的步骤:

DROP PROCEDURE IF EXISTS dbo.RemoveFromQueue
GO
CREATE PROCEDURE dbo.RemoveFromQueue(@absolute_url varchar(400))
AS
BEGIN
    DELETE
    FROM [WebshopCrawler].[dbo].[PriorityQueue]
    WHERE absolute_url = @absolute_url
END
GO


我尝试使用许多不同的索引,但是似乎没有什么可以使过程进行得更快。我希望有人对如何改善它有所了解。

最佳答案

请阅读Using tables as Queues。重要问题:


您必须根据出队策略组织表。 IDENTITY中的主键绝对没有意义。根据优先级和出队顺序使用聚簇索引。
您必须在单个语句中自动出队,使用DELETE ... OUTPUT ...


因此,应该遵循以下原则:

CREATE TABLE PriorityQueue
(
  priority int not null,
  enqueue_time datetime not null default GETUTCDATE(),
  absolute_url varchar (8000) not null,
  depth int not null,
  domain_host varchar (255) not null,
);

CREATE CLUSTERED INDEX PriorityQueueCdx on PriorityQueue(priority DESC, enqueue_time);

CREATE PROCEDURE dbo.Dequeue
AS
BEGIN
    with cte as (
       SELECT top 1 absolute_url, depth, priority
       FROM [PriorityQueue] with (rowlock, readpast)
       ORDER BY priority DESC, enqueue_time)
     DELETE FROM cte
         OUTPUT DELETED.*;
END
GO

关于sql - SQL Server中的优先级队列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40864484/

10-14 12:54