我有几百万个域名的SQL表。但现在当我搜索让我们说
SELECT *
FROM tblDomainResults
WHERE domainName LIKE '%lifeis%'
获得结果需要10分钟以上。我试过索引,但没有帮助。
存储这数百万条记录并在短时间内轻松访问这些信息的最佳方法是什么?
到目前为止,大约有5000万条记录和5列。
最有可能的是,您尝试使用传统索引来优化LIKE查询,除非模式以固定字符串开头(例如'lifeis%')。
您的查询所需的是全文索引。如今大多数DBMS都支持它。
全文索引在这里是最好的选择 - 如何实现这取决于你正在使用的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);
加载新数据时,请检查是否有任何新域名 - 并将其插入域名表中。然后在您的大表中,您只需包含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子句。
停止使用LIKE语句。你可以使用fulltext search,但它需要MyISAM表,并不是那么好的解决方案。
您可能想要考虑的一件事是为这种查找提供单独的搜索引擎。例如,您可以使用SOLR(lucene)服务器搜索并检索与您的搜索匹配的条目ID,然后通过id从数据库中检索数据。即使不得不拨打两个不同的电话,它很可能会更快。
每当必须查找(“书签查找”)索引本身不包含的数据时,索引就会变慢。例如,如果您的索引有2列,ID和NAME,但是您选择*(总共5列)数据库必须读取前两列的索引,然后查找其他3列的索引。其他地方的数据结构效率较低。
在这种情况下,由于“喜欢”,您的索引无法使用。这类似于不在查询上放置任何过滤器,它将完全跳过索引,因为它必须读取整个表,无论如何它只会这样做(“表扫描”)。有一个阈值(我认为发动机通常翻转到35-50%左右)。
简而言之,您似乎不太可能需要数据库中的所有5000万行用于生产应用程序,但如果您这样做...使用具有更多内存的计算机并尝试将这些数据保存在内存中的方法。也许No-SQL DB是更好的选择 - mongoDB,沙发DB,东京内阁。这样的事情。祝好运!
您可以尝试将域分解为块,然后自己搜索块。几年前,当我需要在句子中搜索单词时,我做了一些事情。我没有全文搜索,所以我将句子分成单词列表并搜索单词。由于单词被索引,因此找到结果真的很快。