【问题标题】:How do I ask for help optimizing & fixing queries in MySQL?如何寻求帮助优化和修复 MySQL 中的查询?
【发布时间】:2010-11-15 07:40:58
【问题描述】:

MySQL 问题是 StackOverflow 上我最喜欢的一些问题。

不幸的是,这样的事情:

SELECT foo, bar, baz, quux, frozzle, lambchops FROM something JOIN somethingelse ON 1=1 JOIN (SELECT * FROM areyouserious) v ON 0=5 WHERE lambchops = 'good';

让我的眼睛流血。

此外,描述架构的尝试通常是这样的:

我有一个表 CrazyTable,其中有一列是日期,它的主键是 Foo_Key,但我想使用与月相有关的 column_bar 的子字符串(在 CrazyTable 中)加入 SOMETABLE(我将它作为三次序列化的 PHP 数组存储在 moon_phases 中)。

这是我提出的一个问题的示例,如果我没有按照以下步骤操作,我永远不会从任何人那里得到满意的答案:I have no shame.

我将在下面回答最能帮助您获得问题的最佳答案的方法。什么对有帮助?

【问题讨论】:

  • 有点题外话了,但是在使用代码块时,有没有一种简单的方法可以添加标签,还有什么?我喜欢格式化我的代码,以便于阅读,但很多时候我最终在我的回复中编码并且只是放了几个空格。
  • @rezzif:根据我的代码块的长度,我会做两件事之一。小:在答案框中键入代码,在一行的开头插入 4 个空格,复制 4 个空格,粘贴在其他行的前面。大:在文本编辑器(VIM 或 TextMate)中编写我的代码,并使用它们的缩进功能将其缩进 4 个空格,然后我只是剪切和粘贴。
  • @hobodave 是的,这几乎就是我现在所做的 - 只是想知道是否适合这种格式。

标签: mysql optimization


【解决方案1】:

使用 SHOW CREATE TABLE


这比你的话更能告诉我关于你的桌子的信息:

mysql> show create table magic\G
*************************** 1. row ***************************
       Table: magic
Create Table: CREATE TABLE `magic` (
  `id` int(11) DEFAULT NULL,
  `what` varchar(255) DEFAULT NULL,
  `the` datetime DEFAULT NULL,
  `heck` text,
  `soup_is_good` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

CAVEAT:如果表中有 70 列,省略不必要的列。需要什么?

  • 加入的字段
  • 已选择字段
  • 字段在哪里

使用解释


这让我了解如何最好地优化您当前工作但可能很慢的查询:

mysql> explain select *     from magic\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: magic
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
        Extra: 
1 row in set (0.00 sec)

使用 \G


必须向右滚动通常会带来不便。

通常:

mysql> select * from magic;
+------------+-------------------------------+---------------------+-------------------+--------------+
| id         | what                          | the                 | heck              | soup_is_good |
+------------+-------------------------------+---------------------+-------------------+--------------+
| 1000000000 | A really long text string yay | 2009-07-29 22:28:17 | OOOH A TEXT FIELD |        100.5 | 
+------------+-------------------------------+---------------------+-------------------+--------------+
1 row in set (0.00 sec)

更好:

mysql> select * from magic\G
*************************** 1. row ***************************
          id: 1000000000
        what: A really long text string yay
         the: 2009-07-29 22:28:17
        heck: OOOH A TEXT FIELD
soup_is_good: 100.5
1 row in set (0.00 sec)

CAVEAT: \G 显然将一行数据变成了几行。对于多行数据,这变得同样繁琐。做看起来最好的事情。

为令人讨厌的大数据块使用外部粘贴箱:

让我们知道您的期望


  • 慢? - 我们不知道什么是慢。秒、分、小时?这有助于了解。
  • 更快 - 我们也不知道。您对快速的期望是什么?
  • 频率 - 这是您计划只运行一次的查询吗?日常的?每天数百或数千次?这有助于我们知道何时足够好

【讨论】:

    【解决方案2】:

    程序分析

    select * from yourtable procedure analyse()\G
    

    以上将让其他人知道存储在表中的最大值和最小值。这有帮助。

    【讨论】:

      【解决方案3】:

      知道你在相关表上有哪些索引是至关重要的,imo。您声明您在 where 子句中使用 column_bar 的子字符串 - 您可能需要将此子字符串反规范化并将其存储在另一列中,然后对其进行索引。如果(例如)仅存在 2 个不同的值,则该列的基数再次会使使用该列上的索引变得毫无价值。有关性能调优最佳实践的有用视频教程,请观看 Jay Pipes 的 youtube video

      【讨论】:

      • 我不是在寻求帮助。我的问题中的例子就是这样,例子。 SHOW CREATE TABLE 也显示索引。
      • 你在最后的句子中问了(这推断出你在问什么)“什么对你有帮助?”我看不出我的答案有什么不足——我输入的内容在优化和修复 Mysql 中的查询方面确实帮助了我。不过,你的问题,你的规则,你的业力。
      • 哦,我明白了 - 你以为我已经对你的代码进行了深入分析(如果我有的话,会更加冗长)。也许我可以更好地表达它,但是应该更好地指出视频教程的链接。现在理解你的评论(我认为)..
      • “您声明您在 where 子句中使用 column_bar 的子字符串 - 您可能需要将此子字符串反规范化并将其存储在另一列中,然后对其进行索引。” - 你的措辞可能需要大量的工作。在我看来,你接受了那个奇特的查询,并试图分析它并建议我如何改进它。
      • 我删除了我的反对票,因为我误会了你。你的答案仍然是神秘而令人困惑的 imo。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      • 1970-01-01
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多