<p>这是您的程序,使用Python自己的<code>sqlite3</code>和<a href="https://mtgjson.com/downloads/all-files/" rel="nofollow noreferrer">https://mtgjson.com/downloads/all-files/</a>方便地提供的SQLite数据库,转换为基于SQL的方法:</p>
<pre><code>import sqlite3
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
conn = sqlite3.connect(r"C:\Users\Tomalak\Downloads\AllPrintings.sqlite")
conn.create_function("SIMILAR", 2, similar)
def find_similar_cards(key_val):
return conn.execute("""
SELECT
c.number, c.name, c.type, c.artist, c.multiverseId,
fd.name AS local_name, fd.language
FROM
cards AS c
INNER JOIN foreign_data AS fd ON fd.uuid = c.uuid
WHERE
SIMILAR(fd.name, ?) > 0.85
""", [key_val])
for row in find_similar_cards("Arc électrique"):
print(row)
</code></pre>
<p>你可以看到,当你阅读它的时候,它会立即变得更加明显,所以这已经是一个很大的优点了</p>
<p>SQLite允许导入用户定义的函数,并使它们可用于SQL查询,因此我导入了<code>SequenceMatcher</code></p>
<p>不幸的是,这也是罪魁祸首。它必须扫描<code>foreign_data</code>中237000条记录中的每一条,并分析每一条<code>name</code>的相似性值。这是一个缓慢的过程,对此我们也无能为力。在我的(较旧的)笔记本电脑上,完成此查询和打印只需10秒多一点</p>
<pre>
('97', 'Arc Lightning', 'Sorcery', 'Seb McKinnon', '386478', 'Arc électrique', 'French')
('97', 'Arc Lightning', 'Sorcery', 'Seb McKinnon', '394068', 'Arc électrique', 'French')
('174', 'Arc Lightning', 'Sorcery', 'Andrew Goldhawk', '5733', 'Arc électrique', 'French')
</pre>
<p>但仍有优化的空间。<code>foreign_data</code>表只包含160000个不同的名称。可以使用那些唯一的名称创建一个helper表,以便更快地进行扫描,然后重新连接到<code>cards</code>表。但无论你做什么,搜索“模糊”值总是需要一些时间</p>
<p>一般来说,改进搜索时间的选项包括</p>
<ul>
<li>减少工作量(即在记录较少的表上工作,如“仅限不同的名称”)</li>
<li>使用更快的比较机制(即从SequenceMatcher切换到其他设备)</li>
<li>使用预先计算的结果(不适用于所有情况,例如不适用于这种情况)</li>
<li>可能:使用全文索引(<a href="https://sqlite.org/fts3.html" rel="nofollow noreferrer">SQLite supports that</a>。可能需要一些时间才能理解它,但最终可能是值得的。全文索引非常快速,而且相当“模糊”)</li>
</ul>
<p>除此之外,下载的SQLite DB根本没有定义索引,这取决于您经常查询的数据类型,这里也有改进的余地</p>
<p>一旦您不搜索计算值,并且适当的索引已经就位,这将非常迅速</p>