代码格式化SQL查询


17

我应该在不同的行中中断SQL查询吗?例如,在我正在进行的项目中,我们有一个查询,该查询占用1600列!1600 +制表符。我写了这样的查询:

   "SELECT bla , bla2 , bla FROM bla " . 
     "WHERE bla=333 AND bla=2" . 
      "ORDER BY nfdfsd ...";

但是他们要求我将它们放在一行中,并说我的样式格式不好。为什么这是不好的做法?


反对可能是使用插值引号(双引号)和串联(.),我已经看到一些程序员将性能成本归咎于此。
布鲁斯·奥尔德森,2010年

3
一切都必须在一条线上吗?您好滚动条,再见易读。
mike30年

1
@BruceAlderson听起来像是2000年代初期的文章之一“家庭主妇发现了3个优化PHP的简单技巧”。当您开始插入变量而没有适当地转义变量以创建SQL注入攻击时,会出现带有双引号和/或串联的真正的红旗。
肖恩·麦克索明

1
是否使用任何“内部”工具来处理文件?
伊恩

为什么很难理解,只要您获得代码的报酬,就可以编写,编写干净,整洁,有序的代码?
图兰斯·科尔多瓦

Answers:


33

由于源代码控制的原因,我们在每个where子句或逗号后都有换行符。所以你的以上变成

SELECT bla 
     , bla2 
     , bla 
FROM   bla 
WHERE  bla=333 
  AND  bla=2
ORDER  BY nfdfsd
        , asdlfk;

(制表符和对齐方式在这里没有标准,但是逗号通常是领先的)

仍然,没有任何性能差异。


5
好主意,这将使一个小的更改在源代码控制差异中非常出色。
Carson63000

与我使用的格式几乎相同,尽管我通常将所有选择列表放在一行上(如果有很多列,则放在多行上)
Dean Harding 2010年

7
这里的布局相似,只是逗号之间有区别,最后是逗号。
DBlackborough 2010年

4
@ m.edmondson-源代码管理版本之间的差异突出显示了逐行的更改。使用这种格式,每一行包含一小部分信息-列名,表名,联接或顺序子句-这意味着差异将直接指向更改的内容,而不仅仅是指向包含许多内容的行并让您离开找出不同之处。
乔恩·霍普金斯

2
这种格式还使在开发过程中注释掉单个项目以及使用剪切和粘贴更改顺序变得容易。
克里斯·纳瓦

14

1600列的查询听起来似乎需要优秀的DBA进行认真的审查。

如果查询很复杂,我将其包装起来。如果简单明了,除非它将太长,否则我将其保留为一行,然后我将再次开始包装它。

一切都是关于可管理性和理解应该做什么,因此包装或不包装可以在运行中决定,除非您的组织有一些关于它的代码格式化规则。

回复:这是不好的编码习惯。几乎不!这是很好的做法。我不知道有那么长的时间使用查询的充分理由,而且有很多重新格式化它的充分理由。正如我之前说过的,熟练的DBA可能需要进行处理。


3
同意,这全都归结为可读性。性能等完全不受美学影响。
克里斯蒂安

同意性能不是一个很好的论据。
Tin Man

我不知道..只是告诉我将其保持在一行中,也许是因为他们这样做了
GorillaApe 2010年

如果是“旧版”代码,他们可能会害怕触摸它。慢慢地走开,一切都会好起来的。
Tin Man

它的新代码...
GorillaApe

8

想到的单行查询的唯一优点是,这些查询对于grep而言可能更容易一些。但是除此之外,我很沮丧。就个人而言,我更喜欢可读性更强的查询。


6

多行注释很好,在处理大量SQL时几乎至关重要。而且,如果您的编程语言带有Heredoc引号,那就更好了(因为许多编辑器都可以在其中突出显示SQL语法)。

例:

$a = SQL<<<
    SELECT a, b, c, d
    FROM Foo f
    WHERE f.a = ?
SQL;

当处理数十行(或数百行)的查询时,缩进和空格都使文本可行。


1
对于PHP,nowdocs是单引号形式(即,没有变量替换)。
艾伦·皮尔斯

4

看来这似乎是专门针对在各种编程语言中定义一个大查询,因为您将查询放在字符串文字中并将其连接起来。

如果它是一种编译语言,那么它根本不会有任何区别-编译器将执行的第一个优化操作之一是将字符串文字自动连接在一起,因此无论如何您最终都会得到一个大字符串。

至于语法,您实际上应该考虑将查询移出代码之外-将查询存储在单独的.sql资源文件中,并让软件读取该文件。如果不是动态构建的查询,则对变量使用准备好的语句(即,根据某些参数添加了where子句等)。如果是动态构建的,则可以添加自己的替换变量,并在需要的位置和时间插入额外的参数。

至于1600栏,我强烈建议您为此建立一个视图,

SELECT column1, column2, .... column1600 from X where Y

你会得到

选择*从viewX在哪里

您自己的代码更加简洁。


+1,我也考虑将查询放入存储过程中
Larry Coleman 2010年

1

我经常使用@glasnt提出的格式对复杂的查询进行故障排除,但是通常将查询放在一行中。

这可能无法回答您的问题,但是我也强烈建议您将查询分解为较小的查询。显然,这取决于查询,但是添加到查询中的子句和联接越多-SQL引擎优化查询的能力就越低。

您的数据库供应商应该拥有MySQL的EXPLAIN(或MSSQL的SHOWPLAN_ALL设置)之类的工具,每当数据库必须创建一个临时表或类似的表时,它就会向您显示数据库在幕后如何优化查询。当您谈论多个并发用户时,会有很大的延迟。

通过将看似琐碎的逻辑从SQL中移出并移入代码中,可以显着提高性能-SQL非常擅长简单操作。

这可能与您有关,因此显而易见的好处是,您的查询要简单得多,易于阅读-易于管理(不超过1600列),并且速度更快。绝对是一场全面胜利。

希望这可以帮助 :)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.