王新阳

wangxinyang

mysql两表组合查询的一种优化方法

表tab_product表为产品表

表tab_class为产品与分类对照表,一个产品可能属于多个分类

首页要确保 tab_class 表有 classid和productid 的复合索引

ALTER TABLE tab_class ADD INDEX idx_classid_productid (classid, productid);	

JOIN 组合查询:

SELECT `tab_product`.*
FROM `tab_product`
JOIN `tab_class` ON `tab_product`.`id`=`tab_class`.`productid`
WHERE `tab_class`.`classid` IN(3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606)
GROUP BY `tab_product`.`id`
ORDER BY `id` DESC LIMIT 10;

EXISTS 查询:

SELECT *
FROM `tab_product`
WHERE `id` IN(
    SELECT DISTINCT(productid) 
    FROM tab_class 
    WHERE classid IN(3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606)
)
ORDER BY `id` DESC LIMIT 10;

在CodeIgniter中的写法:

$class_ids = [3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606];

$this->db->from('tab_product');
$this->db->where_in('id', "
    SELECT DISTINCT(productid) 
    FROM tab_class 
    WHERE classid IN (".implode(',', $class_ids).")
");
$this->db->order_by('id', 'DESC');
$this->db->limit(10);
$query = $this->db->get();

SELECT DISTINCT(productid) 中的 DISTINCT 可以省略,因为外层的 IN 会自动去重复。但如果结果集比较大还是建议加上。

也可以使用 EXPLAIN 查询两种方法的性能,择优使用

2025-09-25
2025-10-14 星期二 农历八月二十三