【问题标题】:PHP SQLite like slowPHP SQLite 喜欢慢
【发布时间】:2014-02-04 18:18:16
【问题描述】:

我正在尝试分析网络流量。流量被保存到一个大约 300MB 的 SQLite 文件中,我正在尝试梳理该文件以查找关键字。

我有大约 10 个关键字,我为其生成突变(反向字符串、哈希等),每个关键字大约有 20 个变体。为了找到这些排列,我为每个关键字生成一个查询,该查询包括一个命令中的所有排列,用 OR 分隔。一个查询如下所示:

SELECT * FROM flows 
WHERE 
(buffer LIKE :permutationOne) OR 
(buffer LIKE :permutationTwo) OR 
(buffer LIKE :permutationThree) OR
…
(buffer LIKE :permutationTwenty)

SQLite 通信和语句绑定的初始化如下所示:

$sqlite = new PDO('sqlite:resources/traffic.sqlite'); // executed once

// done for each keyword
$statement = $sqlite->prepare($sqlCommand);
$statement->execute([':permutationOne' => '%perm1%', ':permutationTwo' => '%perm2%', …]);

我测量了执行这十个查询所需的时间,它在 150 到 300 秒之间变化,具体取决于执行查询的设备。由于文件很大,我执行了 10 个查询,每个查询有 20 个类似字符串,我想知道是否有办法优化查询?如果可能的话,我非常希望至少将执行时间减半。或者也许我应该使用另一个库而不是 PDO?

【问题讨论】:

    标签: php performance sqlite sql-like


    【解决方案1】:

    好的。我们在我的另一个答案中决定索引在这种情况下无济于事。如果您被 sqlite 卡住了,那么您可以使用 全文搜索 (FTS) 引擎。它包含在源代码中,但是您必须在打开此功能的情况下重新编译 sqlite 的麻烦。

    更多信息:

    http://answers.oreilly.com/topic/1955-how-to-use-full-text-search-in-sqlite/

    【讨论】:

      【解决方案2】:

      对数据库(LIKE '%somehing%')执行这种操作非常昂贵。为了提高性能,我建议您为相关字段编制索引,或使用像 Sphinx (http://sphinxsearch.com/about/sphinx/) 这样的全文搜索服务器。

      【讨论】:

      • 感谢您的快速回复。我不得不承认我从来没有手动添加过索引。我必须在每个查询中都这样做吗?另外,如何使用该索引?
      • 另外,根据 SQLite 优化指南,LIKE 不是使用索引的操作,但是将整个文件上传到 sphinx 比简单地执行无索引扫描需要更长的时间。
      【解决方案3】:

      编辑:

      这个答案没有解决问题,但如果某些条件为真,sqlite 将使用LIKE query optimization。不得使用通配符作为搜索字符串的第一个字符。我将把这个答案留在这里,因为它可能有助于其他 LIKE 优化。

      旧答案:

      我之前已经对 sqlite 性能进行了故障排除。通过键入sqlite3 databasefile 打开您的数据库。 以下是我在 sqlite3 命令行中使用的一些命令:

      .help
      .timer ON
      .explain ON -- optional
      explain query plan SELECT BLAH FROM BLAH WHERE BLAH
      

      如果您看到SCAN,那就不好了。如果您看到SEARCH,它正在使用索引。您可以添加索引来提高 SELECT 性能。

      您可以在 sqlite3 命令行中尝试这样的索引:

      CREATE INDEX flows_idx1 ON flows (buffer);
      

      这将创建索引作为数据库架构的一部分,这意味着您不必重新创建它。除非您drop 它,否则它将从此存在。 sqlite3 查询优化器将查看您的SELECT 并查看索引是否有助于加快速度。您根本不需要更改 SELECT 查询。

      另请参阅Sqlite optimization documentation

      【讨论】:

      • 谢谢。不过,我不确定如何使用该索引。添加一次就足够了,还是我必须为每个查询都添加一次?另外,这样做是否足够,还是我必须以某种方式在我的选择中引用该索引?
      • 谢谢。顺便说一句,根据优化文档,索引不能用于 LIKE 操作。仅适用于 IN、IS 和比较运算符。
      • "字符串字面量不能以通配符开头;" 这就是问题所在。否则索引可能有用。
      • 不幸的是,就我而言,它必须这样做。我要查找的字符串可以位于传输数据中的任何位置。
      猜你喜欢
      • 2011-11-11
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      相关资源
      最近更新 更多