衡量SQL语句的复杂性

epo*_*ter 27 sql static-analysis cyclomatic-complexity

大多数编程语言中方法的复杂性可以使用静态源代码分析器在圈复杂度中进行测量.是否有类似的度量标准来衡量SQL查询的复杂性?

它很简单,可以衡量返回查询所需的时间,但如果我只想量化查询的复杂程度呢?

[编辑/注意]虽然获得执行计划很有用,但在这种情况下,这并不一定是我想要识别的.我不是在寻找服务器执行查询的难度,我正在寻找一个指标来确定开发人员编写查询的难度,以及包含缺陷的可能性.

[编辑/注释2]不可否认,有时候测量复杂性没有用,但有时也是如此.有关该主题的进一步讨论,请参阅此问题.

pas*_*cal 10

我不确定查询计划的检索是否会回答这个问题:查询计划隐藏了在返回(或在过滤器中使用)之前对数据执行的计算的复杂性的一部分; 查询计划要求有意义的数据库是相关的.事实上,复杂性和执行时间有些相反; 像"好,快,便宜 - 挑选任何两个"之类的东西.

最终是关于犯错误的机会,还是不理解我写的代码?

就像是:

  • 表次数(1
  • 每个连接表达式+1(每个外连接+1)?
  • 每个谓词后+1 WHERE或+1HAVING
  • 每个GROUP BY表达式+1
  • +1元UNIONINTERSECT
  • 每个函数调用+1
  • 每个CASE表达式+1
  • )


Ira*_*ter 10

软件复杂性的常用度量包括Cyclomatic Complexity(衡量控制流程复杂程度)和Halstead复杂度(算术复杂程度).

SQL查询中的"控制流"最好与查询中的"和"和"或"运算符相关.

"计算复杂度"最好与SUM或隐式JOINS等运算符相关.

一旦您决定如何对SQL查询的每个语法单元进行分类,无论它是"控制流"还是"计算",您都可以直接计算Cyclomatic或Halstead度量.

认为 SQL优化器对查询的作用绝对无关紧要.复杂性度量的目的是表征一个人理解查询的难度,而不是如何有效地评估它.

同样,DDL所说的内容或是否涉及观点不应包含在此类复杂性措施中.这些指标背后的假设是,当你简单地调用它时,使用抽象中的机器的复杂性并不重要,因为可能是抽象做了编码器很好理解的事情.这就是为什么Halstead和Cyclomatic测量在他们的计数中不包括被调用的子例程的原因,我认为你可以做出一个很好的例子,视图和DDL信息就是那些"被调用"的抽象.

最后,这些复杂性数字的完美正确性或多么完美错误并不重要,只要它们反映了复杂性的一些真实性,您就可以相互比较它们.通过这种方式,您可以选择最复杂的SQL片段,从而将它们全部排序,并将测试注意力集中在最复杂的片段上.