Mysql LEFT加入大数据表

时间:2014-03-16 16:00:40

标签: php mysql sql

我有一个名为" tables_data_info" where存储了一些相对于不同表的数据。数据类似于"创建时间","编辑时间","编辑用户","按用户ID创建"我使用这个表是因为有一个动态的PHP脚本可以自动生成它。 但是,当我拥有大量的记录(在这种情况下为15k)时,查询变得非常非常慢,并且需要花费很长时间(#34;分钟"做他的工作!但我没有选择所有15k记录,我只限制选择10条记录! 一个简单的查询:

SELECT pd.id, pd.title, pd.sell_price, pd.available_qt, tdi.createtime, tdi.lastupdatetime, tdi.create_member_id, tdi.create_group_id, tdi.last_update_member_id, tdi.last_update_group_id FROM zd_products AS pd LEFT JOIN zd_tables_data_info AS tdi ON ( tdi.targetid = pd.id and tdi.table_name = 'products' ) ORDER by pd.title ASC LIMIT 0, 10

如何以不同的方式运行此查询,但效率更高?

这里是表结构:

zd_products

CREATE TABLE `zd_products` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(256) NOT NULL DEFAULT '',
  `internalcode` varchar(256) DEFAULT NULL,
  `ean13_jan_code` varchar(256) DEFAULT NULL,
  `upc_code` varchar(11) DEFAULT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '0',
  `status` varchar(12) NOT NULL DEFAULT 'new',
  `product_tags` longtext,
  `buy_price` double NOT NULL DEFAULT '0',
  `sell_price` double NOT NULL DEFAULT '0',
  `fiscal_tax_id` int(11) NOT NULL DEFAULT '0',
  `box_width` double NOT NULL DEFAULT '0',
  `box_height` double NOT NULL DEFAULT '0',
  `box_depth` double NOT NULL DEFAULT '0',
  `box_weight` double NOT NULL DEFAULT '0',
  `shipment_extra_price` double NOT NULL DEFAULT '0',
  `available_qt` int(11) NOT NULL DEFAULT '0',
  `allow_purchase_out_stock` tinyint(1) NOT NULL DEFAULT '0',
  `meta_title` varchar(256) DEFAULT NULL,
  `meta_description` varchar(256) DEFAULT NULL,
  `meta_keywords` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15730 DEFAULT CHARSET=utf8;

zd_tables_data_info

CREATE TABLE `zd_tables_data_info` (
  `table_name` varchar(256) NOT NULL DEFAULT '',
  `targetid` int(11) DEFAULT NULL,
  `create_member_id` int(11) unsigned DEFAULT NULL,
  `create_group_id` int(11) unsigned DEFAULT NULL,
  `last_update_member_id` int(11) unsigned DEFAULT NULL,
  `last_update_group_id` int(11) unsigned DEFAULT NULL,
  `createtime` int(11) unsigned DEFAULT NULL,
  `lastupdatetime` int(11) unsigned DEFAULT NULL,
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`),
  KEY `INDEX` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19692 DEFAULT CHARSET=utf8;

1 个答案:

答案 0 :(得分:2)

您的数据不是特别大。这是查询:

SELECT pd.id, pd.title, pd.sell_price, pd.available_qt,
       tdi.createtime, tdi.lastupdatetime, tdi.create_member_id, tdi.create_group_id,
       tdi.last_update_member_id, tdi.last_update_group_id
FROM zd_products pd LEFT JOIN
     zd_tables_data_info tdi
     ON tdi.targetid = pd.id and tdi.table_name = 'products'
ORDER by pd.title ASC
LIMIT 0, 10;

您可以使用索引提高此查询的性能。我想到的两个是zd_products(title, id)zd_tables_data_info(targetid, table_name)。试试这些,看看它们是否有帮助。您可以在create table语句(或alter table)中创建这些索引,也可以使用:

create index zd_products_title_id on zd_products(title, id);
create index zd_tables_data_info_targetid_table_name on zd_tables_data_info(targetid, table_name);

如果没有,请将explain放在查询前面,然后使用生成的计划修改您的问题。