使用子查询在表中检查记录的效率是多少?

时间:2016-10-26 08:51:05

标签: mysql sql database

我有这样的查询。我有CC.key1,CC.key2的复合索引。 我正在一个大型数据库中执行它

[DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
public static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved);

//If VisualElements/DisplayName contains ms-resource: then call the below
//function. identity is nothing but package name that can be retrieved from
//Identity/Name element in AppxManifest.xml.

private static string GetName(string installPath, string name, string identity) {
    StringBuilder sb = new StringBuilder();
    int result;

    //if name itself contains the package name then assume full url else 
    //format the resource url

    var resourceKey = (name.ToLower().Contains(identity.ToLower())) ? name : string.Format("ms-resource://{0}/resources/{1}", identity, name.Split(':')[[1]].TrimStart('/'));
    string source = string.Format("@{{{0}? {1}}}", Path.Combine(installPath, "resources.pri"), resourceKey);
    result = SHLoadIndirectString(source, sb, -1, IntPtr.Zero);

    if (result == 0)
        return sb.ToString();

    //if the above fails then we try the url without /resources/ folder
    //because some apps do not place the resources in that resources folder

    resourceKey = string.Format("ms-resource://{0}/{1}", identity, name.Split(':')[[1]].TrimStart('/'));
    source = string.Format("@{{{0}? {1}}}", Path.Combine(installPath, "resources.pri"), resourceKey);
    result = SHLoadIndirectString(source, sb, -1, IntPtr.Zero);

    if (result == 0)
        return sb.ToString();
    return string.Empty;
}

我试图将其作为内部联接,但速度越来越慢。我该如何优化此查询?

3 个答案:

答案 0 :(得分:2)

这里的技巧是能够清楚地表达问题的查询:

Django-app/
    app/
    templates/
        base.html
    static/
        node_modules/ # will contain all libraries
        angular_app/
            app.js
            controllers.js

<强>解释

如果SELECT * FROM CC t1 INNER JOIN ( SELECT cc.key1, cc.key2 FROM CC cc LEFT JOIN Service s ON cc.key1 = s.sr2 AND cc.key2 = s.sr1 GROUP BY cc.key1, cc.key2 HAVING COUNT(*) <= 2 OR SUM(CASE WHEN cc.key = 'new' THEN 1 ELSE 0 END) > 2 ) t2 ON t1.key1 = t2.key1 AND t1.key2 = t2.key2 中具有给定CCkey1值的给定记录与{{1}中的相应记录匹配,则原始的两个子查询只会添加到计数中表。我的内部查询背后的策略是使用key2来计算发生这种情况的次数,并使用它来代替子查询。第一个计数条件是您的底部子查询,第二个计数是顶部。

内部查询查找Service中与应保留的记录相对应的所有GROUP BYkey1对。并且认识到这两列是原始查询中用于确定是否保留key2的记录的唯一条件。然后,这个内部查询可以再次内部连接到CC以获得最终结果集。

就性能而言,即使这个答案也可能有所不足,但它应该比一个大规模的相关子查询更好,这就是你所拥有的。

答案 1 :(得分:0)

基本上获取必须没有重复的列,然后将它们连接在一起。例如:

select  *
FROM    Table_X A
WHERE   exists (SELECT 1
                FROM   Table_X B
                WHERE  1=1
                 and    a.SHOULD_BE_UNIQUE = b.SHOULD_BE_UNIQUE
                 and    a.SHOULD_BE_UNIQUE2 = b.SHOULD_BE_UNIQUE2
                 /* excluded because these columns are null or can be Duplicated*/
                 --and    a.GENERIC_COLUMN = b.GENERIC_COLUMN
                 --and    a.GENERIC_COLUMN2 = b.GENERIC_COLUMN2
                 --and    a.NULL_COLUMN = b.NULL_COLUMN
                 --and    a.NULL_COLUMN2 = b.NULL_COLUMN2
                 and      b.rowid > a.ROWID);

其中SHOULD_BE_UNIQUE和SHOULD_BE_UNIQUE2是不应重复且具有唯一列的列,并且可以忽略GENERIC_COLUMN和NULL_COLUMNS,因此将它们排除在查询之外。

当我们在重复记录中遇到问题时,一直使用这种方法。

答案 2 :(得分:0)

由于您提供给我们的信息有限,这可能是使用“简化”逻辑重写:

SEELCT * 
  FROM CC NATURAL JOIN
       ( SELECT key1, key2, COUNT(*) AS tally
           FROM Service
          GROUP
             BY key1, key2 ) AS t
 WHERE key3 = 'new' OR tally <= 2;

不确定它是否会表现更好,但可能会给你一些关于下一步尝试的想法?