我在mysql上非常环保,我需要一些清理查询的技巧。它通过一个站点用于多种变体。它有一些subquerys派生表和乐趣继续。继承人查询:
# 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)
答案 0 :(得分:0)
有一件事我注意到这是一个很好的提示(可能是由新的优化器过时),因为一般的性能提升是在需要总计时使用COUNT(1)。 COUNT(*)必须处理列,而COUNT(1)只需要考虑行。
如果这不再是真的,请有人在这里发表评论,我会删除帖子。
另一个提示是永远不要使用SELECT *。通常,您应该始终枚举您选择的列,以便在表更改时隔离代码。
您真正想要做的一件事是将子查询移出SELECT块。联接通常比这些嵌套查询快得多。但请记住,优化器会为我们修复查询做大量的工作。如果优化器已经为我们做了,那么正确编写它可能不会显示出明显的改进!
这是您选择的子查询中的link。
答案 1 :(得分: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
答案 2 :(得分:0)
只是为了表明我在Wouter van Nifterick´s anwswer的评论中的含义。 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'