查询优化-如何更快地搜索SQL表中的数百万条记录



我有几百万个域名的SQL表。但是现在当我搜索比如

SELECT * 
  FROM tblDomainResults 
 WHERE domainName LIKE '%lifeis%'

需要10分钟以上才能得到结果。我试过索引,但没有用。

什么是最好的方法来存储这数百万条记录,并在短时间内方便地访问这些信息?

目前大约有5000万条记录和5列。

最有可能的是,您尝试了传统的索引,它不能用于优化LIKE查询,除非模式以固定字符串开始(例如:"生命是%")。

查询需要的是全文索引。现在大多数DBMS都支持它。

假设您的5000万行表包含重复项(也许这是问题的一部分),并假设SQL Server(语法可能会改变,但概念在大多数rdbms上是相似的),另一个选择是将域存储在查找表中,例如

CREATE TABLE dbo.Domains
(
    DomainID INT IDENTITY(1,1) PRIMARY KEY,
    DomainName VARCHAR(255) NOT NULL
);
CREATE UNIQUE INDEX dn ON dbo.Domains(DomainName);

当您加载新数据时,检查是否有任何域名是新的-并将它们插入Domains表中。然后在大表中,只需要包含DomainID。这不仅会使你的5000万行表更小,还会使这样的查找更有效率。

SELECT * -- please specify column names
FROM dbo.tblDomainResults AS dr
INNER JOIN dbo.Domains AS d
ON dr.DomainID = d.DomainID
WHERE d.DomainName LIKE '%lifeis%';

当然,除了在最小的表上,它总是有助于避免带有通配符的LIKE子句。

全文索引无疑是最好的选择——如何实现将取决于您使用的DBMS。

除此之外,确保在与模式匹配的列上有一个索引将有助于性能,但听起来,您已经尝试过了,并且没有多大帮助。

停止使用LIKE语句。您可以使用全文搜索,但它将需要MyISAM表,并且不是那么好的解决方案。

我建议您检查可用的第三方解决方案-如Lucene和Sphinx。
他们会更优秀。

您可能想要考虑的一件事是为此类查找提供单独的搜索引擎。例如,可以使用SOLR (lucene)服务器搜索并检索与搜索匹配的条目的id,然后按id从数据库检索数据。即使要打两个不同的电话,它也很可能会更快。

索引在查找("bookmark lookup")索引本身不包含的数据时就会变慢。例如,如果索引有2列、ID和NAME,但选择了*(总共5列),那么数据库必须读取前两列的索引,然后再去查找其他地方效率较低的数据结构中的其他3列。

在这种情况下,你的索引不能使用,因为"喜欢"。这类似于在查询中不放置任何where过滤器,它将完全跳过索引,因为无论如何它都必须读取整个表("表扫描")。这是一个阈值(游戏邦注:我认为在35-50%左右,引擎通常会转向这一点)。

简而言之,您似乎不太可能在生产应用程序中需要DB中的所有5000万行,但是如果您这样做……使用内存更大的机器,并尝试将数据保存在内存中的方法。也许一个无sql数据库会是一个更好的选择- mongoDB,沙发数据库,东京内阁。就像这样。好运!

您可以尝试将域分解为块,然后搜索块本身。几年前,当我需要在句子中搜索单词时,我也做过类似的事情。我没有全文搜索,所以我把句子分解成一个单词列表,然后搜索单词。查找结果非常快,因为这些单词都被索引了。

最新更新