MySQL查询查杀我的服务器

时间:2010-04-06 14:01:34

标签: mysql

看看这个查询,我不得不注意到它会让人感到困扰。我跑了7分钟,它只更新了2行。

//set product count for makes
$tru->query->run(array(
    'name' => 'get-make-list',
    'sql' => 'SELECT id, name FROM vehicle_make',
    'connection' => 'core'
));
while($tempMake = $tru->query->getArray('get-make-list')) {
    $tru->query->run(array(
        'name' => 'update-product-count',
        'sql' => 'UPDATE vehicle_make SET product_count = (
            SELECT COUNT(product_id) FROM taxonomy_master WHERE v_id IN (
                SELECT id FROM vehicle_catalog WHERE make_id = '.$tempMake['id'].'
        )
) WHERE id = '.$tempMake['id'],
        'connection' => 'core'
    ));
}

我确信此查询可以进行优化,以便更好地执行,但我无法想到如何执行此操作。

vehicle_make = 45行

taxonomy_master = 11,223行

vehicle_catalog = 5,108行

所有表都有适当的索引

更新:我应该注意,这是一次性脚本,因此只要它运行,开销就不是什么大问题。

CREATE TABLE IF NOT EXISTS `vehicle_make` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `product_count` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=46 ;

CREATE TABLE IF NOT EXISTS `taxonomy_master` (
  `product_id` int(10) NOT NULL,
  `v_id` int(10) NOT NULL,
  `vehicle_requirement` varchar(255) DEFAULT NULL,
  `is_sellable` enum('True','False') DEFAULT 'True',
  `programming_override` varchar(25) DEFAULT NULL,
  PRIMARY KEY (`product_id`,`v_id`),
  KEY `idx2` (`product_id`),
  KEY `idx3` (`v_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `vehicle_catalog` (
  `v_id` int(10) NOT NULL,
  `id` int(11) NOT NULL,
  `v_make` varchar(255) NOT NULL,
  `make_id` int(11) NOT NULL,
  `v_model` varchar(255) NOT NULL,
  `model_id` int(11) NOT NULL,
  `v_year` varchar(255) NOT NULL,
  PRIMARY KEY (`v_id`,`v_make`,`v_model`,`v_year`),
  UNIQUE KEY `idx` (`v_make`,`v_model`,`v_year`),
  UNIQUE KEY `idx2` (`v_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

更新:获得我需要的成功查询就在这里....

SELECT 
        m.id,COUNT(t.product_id) AS CountOf
        FROM taxonomy_master             t
            INNER JOIN vehicle_catalog   v ON t.v_id=v.id
            INNER JOIN vehicle_make      m ON v.make_id=m.id
        GROUP BY m.id;

4 个答案:

答案 0 :(得分:0)

而不是使用嵌套查询, 您可以将此查询分为2个或3个查询,

并在php中将内部查询的结果插入到out查询

它更快!

答案 1 :(得分:0)

@ haim-evgi分离查询不会显着提高速度,只会将负载从数据库服务器转移到Web服务器,并产生在两台服务器之间移动数据的开销。

我不确定您使用适当的索引运行此类查询7分钟。能否请您显示这些查询中涉及的表的表结构。

答案 2 :(得分:0)

没有表/列这是我对逆向工程给定查询的最佳猜测:

UPDATE m
    SET product_count =COUNT(t.product_id)
    FROM taxonomy_master             t
        INNER JOIN vehicle_catalog   v ON t.v_id=v.id
        INNER JOIN vehicle_make      m ON v.make_id=m.id
    GROUP BY m.name

给定代码遍历每个make,然后运行查询每个make的计数。我的回答只是在一个查询中完成它们,并且应该快得多。

每个都有一个索引:

vehicle_make.id      cover on name
vehicle_catalog.id   cover make_id
taxonomy_master.v_id

编辑

尝试一下:

CREATE TEMPORARY TABLE CountsOf (
     id int(11) NOT NULL
     , CountOf int(11) NOT NULL DEFAULT 0.00
);

INSERT INTO CountsOf 
        (id, CountOf )
    SELECT 
        m.id,COUNT(t.product_id) AS CountOf
        FROM taxonomy_master             t
            INNER JOIN vehicle_catalog   v ON t.v_id=v.id
            INNER JOIN vehicle_make      m ON v.make_id=m.id
        GROUP BY m.id;

UPDATE taxonomy_master,CountsOf
    SET taxonomy_master.product_count=CountsOf.CountOf 
WHERE taxonomy_master.id=CountsOf.id;

答案 3 :(得分:0)

好像你需要以下索引:

  1. 在vehicle_catalog上的INDEX BTREE('make_id')
  2. 在taxonomy_master上的INDEX BTREE('v_id')