什么是PostgreSQL的EXPLAIN ANALYZE的MySQL等价物

时间:2011-07-25 06:55:56

标签: mysql sql database postgresql

我想在MySQL中获得类似于PostgreSQL中的EXPLAIN ANALYZE节目的详细查询计划。有没有等价的?

6 个答案:

答案 0 :(得分:14)

编辑:虽然不是直接等效或详细解释分析这里有一些你可以看的工具

mysql提供EXPLAIN和过程分析()
http://dev.mysql.com/doc/refman/5.0/en/explain.html
http://dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html

答案 1 :(得分:8)

在MySQL EXPLAIN EXTENDED之前我没有使用PostgreSQL,它提供的信息比EXPLAIN更多,并且可能会提供您正在寻找的信息。

答案 2 :(得分:3)

为了清楚起见,对已接受的答案发表评论(没有足够的业力来添加评论)

procedure analyze()用于EXPLAIN的不同目的, 它分析指定列的数据集并建议最佳数据类型, 即,当我们有1000行varchar(255)并且想要检查我们真正需要多长时间时,它是有用的,例如。它可能会告诉varchar(23)就足够了

答案 3 :(得分:3)

EXPLAIN EXTENDED

MariaDB / MySQL提供了一个名为EXPLAIN EXTENDED的东西。但是EXPLAIN ANALYZE没有替代品。 EXPLAIN EXTENDED没有提供任何时间信息,内部细分也不那么冗长。

Name: 'EXPLAIN'
Description:
Syntax:
EXPLAIN [explain_type] SELECT select_options

explain_type:
    EXTENDED
  | PARTITIONS

Or:

EXPLAIN tbl_name

The EXPLAIN statement can be used either as a way to obtain information
about how MySQL executes a statement, or as a synonym for DESCRIBE:

o When you precede a SELECT statement with the keyword EXPLAIN, MySQL
  displays information from the optimizer about the query execution
  plan. That is, MySQL explains how it would process the statement,
  including information about how tables are joined and in which order.
  EXPLAIN EXTENDED can be used to obtain additional information.

  For information about using EXPLAIN and EXPLAIN EXTENDED to obtain
  query execution plan information, see
  https://mariadb.com/kb/en/explain/.

o EXPLAIN PARTITIONS is useful only when examining queries involving
  partitioned tables. For details, see
  http://dev.mysql.com/doc/refman/5.5/en/partitioning-info.html.

o EXPLAIN tbl_name is synonymous with DESCRIBE tbl_name or SHOW COLUMNS
  FROM tbl_name. For information about DESCRIBE and SHOW COLUMNS, see
  [HELP DESCRIBE], and [HELP SHOW COLUMNS].

URL: https://mariadb.com/kb/en/explain/

例如,这是taken from this example

EXPLAIN ANALYZE SELECT *
FROM history AS h1
WHERE EXISTS (
  SELECT 1
  FROM history AS h2
  WHERE h1.lead_id = h2.lead_id
  GROUP BY lead_id
  HAVING count(is_first OR NULL) > 1
);

会在PostgreSQL上产生类似的东西,

                                                     QUERY PLAN                                                     
--------------------------------------------------------------------------------------------------------------------
 Seq Scan on history h1  (cost=0.00..82680.50 rows=1100 width=9) (actual time=0.048..0.065 rows=3 loops=1)
   Filter: (SubPlan 1)
   Rows Removed by Filter: 3
   SubPlan 1
     ->  GroupAggregate  (cost=0.00..37.57 rows=1 width=5) (actual time=0.007..0.007 rows=0 loops=6)
           Group Key: h2.lead_id
           Filter: (count((h2.is_first OR NULL::boolean)) > 1)
           Rows Removed by Filter: 0
           ->  Seq Scan on history h2  (cost=0.00..37.50 rows=11 width=5) (actual time=0.003..0.004 rows=2 loops=6)
                 Filter: (h1.lead_id = lead_id)
                 Rows Removed by Filter: 4
 Planning time: 0.149 ms
 Execution time: 0.123 ms
(13 rows)

虽然这是MySQL的等价物,

+------+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id   | select_type        | table | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+------+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
|    1 | PRIMARY            | h1    | ALL  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | Using where |
|    2 | DEPENDENT SUBQUERY | h2    | ALL  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | Using where |
+------+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 2 warnings (0.00 sec)

答案 4 :(得分:2)

MySQL 8.0.18原生引入了EXPLAIN ANALYZE

  

MySQL 8.0.18引入了EXPLAIN ANALYZE ,它运行查询并产生EXPLAIN输出以及时序和基于迭代器的其他信息,这些信息涉及优化器的期望如何与实际执行相匹配。对于每个迭代器,提供以下信息:

     
      
  • 估计执行成本

  •   
  • 估计的返回行数

  •   
  • 返回第一行的时间

  •   
  • 返回所有行的时间(实际费用)

  •   
  • 迭代器返回的行数

  •   
  • 循环数

         

    EXPLAIN ANALYZE只能与SELECT语句一起使用。

  •   

答案 5 :(得分:0)

2020年更新EXPLAIN ANALYZE可用

8.0.18中还提供了旧问题,但仅用于更新,MySQL版本为mysql> explain analyze select count(*) from sbtest1 where k > 500000\G *************************** 1. row *************************** EXPLAIN: -> Aggregate: count(0) (actual time=178.225..178.225 rows=1 loops=1) -> Filter: (sbtest1.k > 500000) (cost=98896.53 rows=493204) (actual time=0.022..147.502 rows=625262 loops=1) -> Index range scan on sbtest1 using idx3 (cost=98896.53 rows=493204) (actual time=0.021..96.488 rows=625262 loops=1) 1 row in set (0.18 sec) ,您可以像下面这样使用它:

input_shape = x_train.shape[1]
n_hidden_1 = 32
n_hidden_2 = 8
output_shape = 1
epochs = 100

class model():
    def __init__(self, input_tensor, lables):
        self.W_1 = tf.Variable(tf.random.normal([input_shape,n_hidden_1]))
        self.W_2 = tf.Variable(tf.random.normal([n_hidden_1,n_hidden_2]))
        self.W_output = tf.Variable(tf.random.normal([n_hidden_2,output_shape]))
        self.B_1 = tf.Variable(tf.random.normal([n_hidden_1]))
        self.B_2 = tf.Variable(tf.random.normal([n_hidden_2]))
        self.B_output = tf.Variable(tf.random.normal([output_shape]))    
        self.var_list= [self.W_1, self.W_2, self.W_output, self.B_1, self.B_2, self.B_output]
    
    def train(self):
        layer_1 = tf.matmul(input_tensor, self.W_1)
        layer_1 = tf.add(layer_1, self.B_1)
        layer_1 = tf.nn.relu(layer_1)
        #2_layer
        layer_2 = tf.matmul(layer_1, self.W_2)
        layer_2 = tf.add(layer_2, self.B_2)
        layer_2 = tf.nn.relu(layer_2)
        #output layer
        output = tf.matmul(layer_2, self.W_output)
        output = tf.add(output, self.B_output)   
        return output

    def loss(self, output):
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels, output))
        return loss

opt = tf.keras.optimizers.SGD(learning_rate=0.1)


input_tensor = tf.convert_to_tensor(x_train, dtype=tf.float32)
size = input_tensor.shape[0]
labels = tf.convert_to_tensor(y_train, dtype=tf.float32)
labels = tf.reshape(labels, (size,1))

model = model(input_tensor, labels)

for epoch in range(epochs):
    
    with tf.GradientTape() as tape:
        output = model.train()
        loss = model.loss(output)
    
    grads = tape.gradient(loss, model.var_list)
    grads_and_vars = zip(grads, model.var_list)
    opt.apply_gradients(grads_and_vars)
    print(loss)