我目前正在使用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
我尝试使用了许多不同的索引,但好像都没有使过程变得更快。我希望有人能提出改进的想法。
default GETUTCDATE()
>> 最好给这个约束命名,而不是让 SQL Server 分配一个随机的名字。我知道这只是举例说明 =) 但是人们可能会盲目地复制它,认为不给约束命名是一个好习惯。 - TT..001和.000的行都会被存储为~.000。你明白我的意思吗?抱歉,这个答案中描述的队列已经损坏了。 - TT.