簡體   English   中英

mysql查詢優化-join和orderby

[英]mysql query optimization - join and orderby

我需要一個mysql查詢優化的幫助。 這是一個簡單的查詢,但是任何不正確的操作我都找不到:-(

我有2個表格:產品(> 40000行)和product_tags(> 500萬)

表1-> N之間有一個關系。 每個產品在表產品標簽中可以有許多標簽。

我有這個簡單的查詢:

EXPLAIN SELECT t.product_id, kwt.tag_id
FROM products AS t, product_tags AS kwt
WHERE 1
AND t.product_id = kwt.product_id
AND kwt.tag_id =11
ORDER BY t.order_date 

wchich返回55個結果。

第一種情況:如果我具有以下表格的表格結構:

CREATE TABLE IF NOT EXISTS `products` (
  `product_id` int(10) unsigned NOT NULL auto_increment,
  `product_source_id` smallint(5) unsigned NOT NULL,
  `order_date` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`product_id`),
  KEY `order_date` (`order_date`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;


CREATE TABLE IF NOT EXISTS `product_tags` (
  `product_tag_id` int(10) unsigned NOT NULL auto_increment,
  `tag_id` int(10) unsigned NOT NULL,
  `product_id` int(11) NOT NULL,
  PRIMARY KEY  (`product_tag_id`),
  KEY `product_id` (`product_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8  ;

那么查詢的解釋是這樣的:

+----+-------------+-------+-------+---------------+------------+---------+---------------------------+-------+-------------+
| id | select_type | table | type  | possible_keys | key        | key_len | ref                       | rows  | Extra       |
+----+-------------+-------+-------+---------------+------------+---------+---------------------------+-------+-------------+
|  1 | SIMPLE      | t     | index | PRIMARY       | order_date | 4       | NULL                      | 45392 | Using index | 
|  1 | SIMPLE      | kwt   | ref   | product_id    | product_id | 4       | t.product_id          |     3 | Using where | 
+----+-------------+-------+-------+---------------+------------+---------+---------------------------+-------+-------------+

它從表產品獲取所有行,但是臨時表沒有任何內容。

第二種情況:如果我在product_tags中為“ tag_id”字段添加索引,則圖片將有所不同:

+----+-------------+-------+--------+-------------------+---------+---------+-----------------------------+------+---------------------------------+
| id | select_type | table | type   | possible_keys     | key     | key_len | ref                         | rows | Extra                           |
+----+-------------+-------+--------+-------------------+---------+---------+-----------------------------+------+---------------------------------+
|  1 | SIMPLE      | kwt   | ref    | product_id,tag_id | tag_id  | 4       | const                       |   55 | Using temporary; Using filesort | 
|  1 | SIMPLE      | t     | eq_ref | PRIMARY           | PRIMARY | 4       | kwt.product_id              |    1 | Using where                     | 
+----+-------------+-------+--------+-------------------+---------+---------+-----------------------------+------+---------------------------------+

現在它只選擇55行,沒錯,但是查詢很復雜:(

我的錯在哪里?

謝謝尼克

這就是我會做的:

閱讀這些資源

重新設計系統以利用集群主鍵

簡化架構:

drop table if exists products;
create table products
(
prod_id int unsigned not null auto_increment primary key,
name varchar(255) not null unique
)
engine = innodb; 

drop table if exists tags;
create table tags
(
tag_id mediumint unsigned not null auto_increment primary key,
name varchar(255) not null unique
)
engine = innodb; 

drop table if exists product_tags;
create table product_tags
(
tag_id mediumint unsigned not null,
prod_id int unsigned not null,
created_date date not null,
primary key (tag_id, prod_id), -- note the clustered composite index and the order !!
key (prod_id)
)
engine = innodb;

測試架構

select
 pt.tag_id,
 pt.prod_id
from
 product_tags pt
inner join products p on pt.prod_id = p.prod_id
where
 pt.tag_id = 11
order by
 pt.created_date
limit 10;

我什至可以將product_tags PK更改為主鍵(tag_id,prod_id,created_date),但這全都取決於您運行的典型查詢。 如果您認為可以提高性能,則可以在創建日期創建一個非聚集二級索引。

希望這可以幫助 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM