1

我对 mysql 非常熟悉,我需要一些关于清理查询的提示。它在整个站点中以多种形式使用。它有一些子查询派生表和乐趣。继承人的查询:

# Query_time: 2  Lock_time: 0  Rows_sent: 0  Rows_examined: 0
SELECT *
  FROM (
  SELECT products . *, categories.category_name AS category, (
  SELECT COUNT( * )
  FROM distros
  WHERE distros.product_id = products.product_id) AS distro_count,
  (SELECT COUNT(*) FROM downloads WHERE downloads.product_id = products.product_id AND WEEK(downloads.date) = WEEK(curdate())) AS true_downloads,
  (SELECT COUNT(*) FROM views WHERE views.product_id = products.product_id AND WEEK(views.date) = WEEK(curdate())) AS true_views
  FROM products
  INNER JOIN categories ON products.category_id = categories.category_id ORDER BY created_date DESC, true_views DESC ) AS count_table
  WHERE count_table.distro_count > 0
  AND count_table.status = 'published'
  AND count_table.active = 1 LIMIT 0, 8

下面是解释:

+----+--------------------+------------+-------+---------------+-------------+---------+------------------------------------+------+----------------------------------------------+
| id | select_type        | table      | type  | possible_keys | key         | key_len | ref                                | rows | Extra                                        |
+----+--------------------+------------+-------+---------------+-------------+---------+------------------------------------+------+----------------------------------------------+
|  1 | PRIMARY            | <derived2> | ALL   | NULL          | NULL        | NULL    | NULL                               |  232 | Using where                                  |
|  2 | DERIVED            | categories | index | PRIMARY       | idx_name    | 47      | NULL                               |   13 | Using index; Using temporary; Using filesort |
|  2 | DERIVED            | products   | ref   | category_id   | category_id | 4       | digizald_db.categories.category_id |    9 |                                              |
|  5 | DEPENDENT SUBQUERY | views      | ref   | product_id    | product_id  | 4       | digizald_db.products.product_id    |   46 | Using where                                  |
|  4 | DEPENDENT SUBQUERY | downloads  | ref   | product_id    | product_id  | 4       | digizald_db.products.product_id    |   14 | Using where                                  |
|  3 | DEPENDENT SUBQUERY | distros    | ref   | product_id    | product_id  | 4       | digizald_db.products.product_id    |    1 | Using index                                  |
+----+--------------------+------------+-------+---------------+-------------+---------+------------------------------------+------+----------------------------------------------+
6 rows in set (0.04 sec)

和表格:

mysql> describe products;
+---------------+--------------------------------------------------+------+-----+-------------------+----------------+
| Field         | Type                                             | Null | Key | Default           | Extra          |
+---------------+--------------------------------------------------+------+-----+-------------------+----------------+
| product_id    | int(10) unsigned                                 | NO   | PRI | NULL              | auto_increment |
| product_key   | char(32)                                         | NO   |     | NULL              |                |
| title         | varchar(150)                                     | NO   |     | NULL              |                |
| company       | varchar(150)                                     | NO   |     | NULL              |                |
| user_id       | int(10) unsigned                                 | NO   | MUL | NULL              |                |
| description   | text                                             | NO   |     | NULL              |                |
| video_code    | text                                             | NO   |     | NULL              |                |
| category_id   | int(10) unsigned                                 | NO   | MUL | NULL              |                |
| price         | decimal(10,2)                                    | NO   |     | NULL              |                |
| quantity      | int(10) unsigned                                 | NO   |     | NULL              |                |
| downloads     | int(10) unsigned                                 | NO   |     | NULL              |                |
| views         | int(10) unsigned                                 | NO   |     | NULL              |                |
| status        | enum('pending','published','rejected','removed') | NO   |     | NULL              |                |
| active        | tinyint(1)                                       | NO   |     | NULL              |                |
| deleted       | tinyint(1)                                       | NO   |     | NULL              |                |
| created_date  | datetime                                         | NO   |     | NULL              |                |
| modified_date | timestamp                                        | NO   |     | CURRENT_TIMESTAMP |                |
| scrape_source | varchar(215)                                     | YES  |     | NULL              |                |
+---------------+--------------------------------------------------+------+-----+-------------------+----------------+
18 rows in set (0.00 sec)

mysql> describe categories
    -> ;
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| category_id      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| category_name    | varchar(45)      | NO   | MUL | NULL    |                |
| parent_id        | int(10) unsigned | YES  | MUL | NULL    |                |
| category_type_id | int(10) unsigned | NO   |     | NULL    |                |
+------------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> describe compatibilities
    -> ;
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| compatibility_id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name             | varchar(45)      | NO   |     | NULL    |                |
| code_name        | varchar(45)      | NO   |     | NULL    |                |
| description      | varchar(128)     | NO   |     | NULL    |                |
| position         | int(10) unsigned | NO   |     | NULL    |                |
+------------------+------------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

mysql> describe distros
    -> ;
+------------------+--------------------------------------------------+------+-----+---------+----------------+
| Field            | Type                                             | Null | Key | Default | Extra          |
+------------------+--------------------------------------------------+------+-----+---------+----------------+
| id               | int(10) unsigned                                 | NO   | PRI | NULL    | auto_increment |
| product_id       | int(10) unsigned                                 | NO   | MUL | NULL    |                |
| compatibility_id | int(10) unsigned                                 | NO   | MUL | NULL    |                |
| user_id          | int(10) unsigned                                 | NO   |     | NULL    |                |
| status           | enum('pending','published','rejected','removed') | NO   |     | NULL    |                |
| distro_type      | enum('file','url')                               | NO   |     | NULL    |                |
| version          | varchar(150)                                     | NO   |     | NULL    |                |
| filename         | varchar(50)                                      | YES  |     | NULL    |                |
| url              | varchar(250)                                     | YES  |     | NULL    |                |
| virus            | enum('READY','PASS','FAIL')                      | YES  |     | NULL    |                |
| downloads        | int(10) unsigned                                 | NO   |     | 0       |                |
+------------------+--------------------------------------------------+------+-----+---------+----------------+
11 rows in set (0.01 sec)

mysql> describe downloads;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| product_id | int(10) unsigned | NO   | MUL | NULL    |                |
| distro_id  | int(10) unsigned | NO   | MUL | NULL    |                |
| user_id    | int(10) unsigned | NO   | MUL | NULL    |                |
| ip_address | varchar(15)      | NO   |     | NULL    |                |
| date       | datetime         | NO   |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

mysql> describe views
    -> ;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| product_id | int(10) unsigned | NO   | MUL | NULL    |                |
| user_id    | int(10) unsigned | NO   | MUL | NULL    |                |
| ip_address | varchar(15)      | NO   |     | NULL    |                |
| date       | datetime         | NO   |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
4

3 回答 3

0

只是为了说明我在Wouter van Nifterick的回答中的评论。IMO,它应该是:

select
  count(myothertable1.id),
  count(myothertable2.id),
  count(myothertable3.id)
from mytable
left outer join myothertable1 on (myothertableid1=mytable.id)
left outer join myothertable2 on (myothertableid2=mytable.id)
left outer join myothertable3 on (myothertableid3=mytable.id)
where mytable.field = 'value'
于 2009-08-07T14:18:11.197 回答
0

我注意到的一件事是一个很好的提示(可能被较新的优化器过时),用于提高一般性能是在你想要一个总数时使用 COUNT(1) 。COUNT(*) 必须处理列,而 COUNT(1) 只需要考虑行。

如果这不再是真的,请有人在此处发表评论,我将删除该帖子。

另一个提示是永远不要使用 SELECT *。通常,您应该始终枚举您选择的列,以便在表更改时避免代码破坏。

您真正想做的一件事是将子查询移出 SELECT 块。连接通常比这些嵌套查询快得多。但请记住,优化器做了大量的工作试图为我们修复我们的查询。如果优化器已经在为我们编写它,那么正确编写它可能不会显示出明显的改进!

这是您选择的子查询的链接

于 2009-06-28T02:16:30.167 回答
0

首先,尝试对查询的格式和缩进做一些事情。像这样很难确切地看到发生了什么。

这个页面做了一个合理的工作来修复格式:http ://www.dpriver.com/pp/sqlformat.htm

无论如何,看起来查询基本上试图显示几个表中的项目数。

而不是这样做:

select
  (select count(*) from myothertable1 where myothertableid=myothertable.id),
  (select count(*) from myothertable2 where myothertableid=myothertable.id),
  (select count(*) from myothertable3 where myothertableid=myothertable.id)
from 
  myothertable

你应该这样做:

select
  count(myothertable1.id),
  count(myothertable2.id),
  count(myothertable3.id)
from 
  mytable,
  myothertable1,
  myothertable2,
  myothertable3
where 
  myothertableid1=mytable.id and
  myothertableid2=mytable.id and
  myothertableid3=mytable.id
于 2009-06-28T02:26:31.957 回答