【问题标题】:Under what circumstances would likelihood() be useful?在什么情况下likelihood() 有用?
【发布时间】:2014-01-25 16:45:14
【问题描述】:

通读sqlite文档我发现了以下函数:

http://www.sqlite.org/lang_corefunc.html#likelihood

likelihood(X,Y) 函数返回参数 X 不变。可能性值 Y (X,Y) 必须是介于 0.0 和 1.0(含)之间的浮点常数。似然(X)函数 是代码生成器优化掉的空操作,因此它在运行期间不消耗 CPU 周期 运行时(即在调用 sqlite3_step() 期间)。可能性的目的(X,Y) 函数是向查询规划器提供一个提示,即参数 X 是一个布尔值,它是 为真,概率约为 Y。不太可能 (X) 函数是 可能性(X,0.0625)。

假设我知道 1 会在 75% 的情况下返回,那么如何:

select likelihood(x,.75) 

帮助查询优化器?

【问题讨论】:

    标签: sqlite query-optimization


    【解决方案1】:

    original example 是这样的:

    考虑以下架构和查询:

    CREATE TABLE composer(
      cid INTEGER PRIMARY KEY,
      cname TEXT
    );
    CREATE TABLE album(
      aid INTEGER PRIMARY KEY,
      aname TEXT
    );
    CREATE TABLE track(
      tid INTEGER PRIMARY KEY,
      cid INTEGER REFERENCES composer,
      aid INTEGER REFERENCES album,
      title TEXT
    );
    CREATE INDEX track_i1 ON track(cid);
    CREATE INDEX track_i2 ON track(aid);
    
    SELECT DISTINCT aname
      FROM album, composer, track
     WHERE cname LIKE '%bach%'
       AND composer.cid=track.cid
       AND album.aid=track.aid;
    

    该模式适用于(简化的)音乐目录应用程序,但在其他情况下也会出现类似类型的模式。有大量的专辑。每张专辑都包含一首或多首曲目。每首曲目都有一个作曲家。每个作曲家可能与多个曲目相关联。

    该查询要求提供每张专辑的名称,该专辑包含一首曲目,其作曲家的名字与“%bach%”匹配。

    查询规划器需要为此查询在几种替代算法中进行选择。最佳选择取决于 表达式 "cname LIKE '%bach%'" 过滤结果的能力。让我们给这个表达式一个“过滤值”,它是一个介于 1.0 和 0.0 之间的数字。值 1.0 表示 cname LIKE '%bach%' 对于作曲家表中的每一行都是正确的。值 0.0 表示 表达式 永远不会为真。

    当前查询计划器(3.8.0 版)假定过滤器值为 1.0。换句话说,它假定 表达式 始终为真。计划者假设最坏情况,因此它将选择一个最小化最坏情况运行时间的计划。这是一种安全的方法,但不是最优的。为 1.0 过滤器选择的计划是 track-album-composer。这意味着“轨道”表在外循环中。对于每一行曲目,在专辑中进行索引查找。然后在 composer 上进行索引查找,然后运行 ​​LIKE 表达式 以查看是否应该输出专辑名称。

    一个更好的计划是轨道作曲家专辑。如果 LIKE 表达式 为假,则第二个计划避免查找专辑。如果过滤器值略小于 1.0,则当前规划器将选择第二种算法。说 0.99。换句话说,如果计划者认为每 100 行中有 1 行的 LIKE 表达式 为假,那么它将选择第二个计划。当过滤器值很大时,这是正确(最快)的选择。

    但在音乐库的常见情况下,过滤器值可能比 1.0 更接近 0.0。换句话说,字符串“bach”不太可能出现在大多数作曲家的名字中。对于接近 0.0 的值,最好的计划是作曲家-曲目-专辑。 composer-track-album 计划是扫描作曲家表一次以查找匹配“%bach%”的条目,并为每个匹配条目使用索引来查找曲目,然后查找专辑。当前的 3.8.0 查询规划器选择这个过滤值小于0.1左右时的第三个方案。

    likelihood 函数为数据库提供了(希望)更好地估计过滤器的选择性。 使用示例查询,它看起来像这样:

    SELECT DISTINCT aname
      FROM album, composer, track
     WHERE likelihood(cname LIKE '%bach%', 0.05)
       AND composer.cid=track.cid
       AND album.aid=track.aid;
    

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 2016-05-12
      • 2011-06-09
      • 2015-01-30
      • 1970-01-01
      • 2011-07-08
      相关资源
      最近更新 更多