【问题标题】:MYSQL where field in select statement too?MYSQL where 字段也在 select 语句中?
【发布时间】:2011-07-22 02:54:41
【问题描述】:

我想从 id = 4 的数据库表中返回字段 name。MYSQL 更容易处理哪个查询。

SELECT name, id FROM table WHERE id = 4

SELECT name FROM table WHERE id = 4

我想我想问是否将WHERE 语句中的字段也放入SELECT 是否是一种好习惯,即使我不会在php 中返回它。

【问题讨论】:

  • 只选择你需要的字段可以节省结果集占用的内存
  • 获取和携带不需要的东西不是一个好习惯

标签: mysql database


【解决方案1】:
SELECT name, id FROM table WHERE id = 4

在mysql的结果中也会有id,它对数据的影响很小,因为它只是一个数字,但是如果你在选择其他东西的地方这样做,比如SELECT name, id FROM table WHERE name = "ron"肯定会不好的做法是从数据库服务器传输更多数据,因为您已经知道名称“ron”,并且由于它不是唯一的,它可能有不止一行。

mysql> explain select id,name from admin_users where id = 1;
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | admin_users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)

mysql> explain select name from admin_users where id = 1;
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | admin_users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)

相比

mysql> explain select id,name from admin_users where name = 'ron';
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | admin_users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
123 row in set (0.11 sec)

mysql> explain select name from admin_users where name = 'ron';
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | admin_users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
123 row in set (0.05 sec)

【讨论】:

    【解决方案2】:

    如果您不需要返回的 id,请不要包含它。如果需要,请包含它。

    【讨论】:

      【解决方案3】:

      不,这不是好习惯。 SELECT 正是您需要的那些字段。

      【讨论】:

        【解决方案4】:

        我想我是在问将字段从 SELECT 中的 WHERE 语句也是如此,即使我不会在 php 中返回它。

        不。当数据在客户端服务器之间传输时,这将增加网络开销。如果您不打算使用数据,请不要选择它。

        【讨论】:

          【解决方案5】:

          除非您在结果中需要“id”列,否则没有理由要求它。 MySQL 将同样对待查询。请求它可能会减慢速度,因为 MySQL 必须向您返回额外的数据,并且您的程序将需要解析它。怀疑它对“id”列很重要,但如果它是几个巨大的文本字段,它可能会。

          这是 MySQL 对我的一个简单表上的两个查询的看法(id 字段上有一个索引)。

          mysql> explain select id,name from admin_users where id = 1;
          +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
          | id | select_type | table       | type  | possible_keys | key     | key_len | ref   | rows | Extra |
          +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
          |  1 | SIMPLE      | admin_users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
          +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
          1 row in set (0.00 sec)
          
          mysql> explain select name from admin_users where id = 1;
          +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
          | id | select_type | table       | type  | possible_keys | key     | key_len | ref   | rows | Extra |
          +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
          |  1 | SIMPLE      | admin_users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
          +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+
          1 row in set (0.00 sec)
          

          【讨论】:

          • 嗯,这取决于admin_users 表的记录数,但是如果您进行详细的分析,您肯定会看到以微秒为单位的差异。
          • 小心。 (0.00 秒) 是指 MySQL 生成查询计划所花费的时间......而不是返回结果所花费的时间。
          • @Philip:一直想问,如何强制mysql测量真正查询执行的时间,除了执行吗?谢谢。
          • @Igor。不知道。我怀疑这是可能的。
          【解决方案6】:

          我怀疑第二种选择,在大型数据库(许多记录 > 1M)上更快,因为从数据库中提取数据所需的时间更少。


          这是对一个小表(1187 条记录)进行的分析,id 是主键:

          mysql> select name,id from websites where id = 1;
          +------+----+
          | name | id |
          +------+----+
          | Shef |  1 |
          +------+----+
          1 row in set (0.00 sec)
          
          mysql> select name from websites where id = 1;
          +------+
          | name |
          +------+
          | Shef |
          +------+
          1 row in set (0.00 sec)
          

          对于第一个查询:

          +----------------------+----------+
          | Status               | Duration |
          +----------------------+----------+
          | starting             | 0.000045 |
          | checking permissions | 0.000006 |
          | Opening tables       | 0.000016 |
          | System lock          | 0.000007 |
          | init                 | 0.000016 |
          | optimizing           | 0.000006 |
          | statistics           | 0.000063 |
          | preparing            | 0.000008 |
          | executing            | 0.000004 |
          | Sending data         | 0.000009 |
          | end                  | 0.000003 |
          | query end            | 0.000002 |
          | closing tables       | 0.000005 |
          | freeing items        | 0.000046 |
          | logging slow query   | 0.000002 |
          | cleaning up          | 0.000002 |
          +----------------------+----------+
          

          对于第二个查询:

          +----------------------+----------+
          | Status               | Duration |
          +----------------------+----------+
          | starting             | 0.000050 |
          | checking permissions | 0.000006 |
          | Opening tables       | 0.000015 |
          | System lock          | 0.000008 |
          | init                 | 0.000017 |
          | optimizing           | 0.000008 |
          | statistics           | 0.000044 |
          | preparing            | 0.000008 |
          | executing            | 0.000002 |
          | Sending data         | 0.000009 |
          | end                  | 0.000003 |
          | query end            | 0.000002 |
          | closing tables       | 0.000005 |
          | freeing items        | 0.000046 |
          | logging slow query   | 0.000002 |
          | cleaning up          | 0.000002 |
          +----------------------+----------+
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-12-07
            • 2012-10-11
            • 1970-01-01
            • 2016-12-29
            • 1970-01-01
            • 2011-01-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多