简体   繁体   中英

Mysql LEFT Join on big data table

I have a table called "tables_data_info" where is stored some of the data relative to different tables. Data like "created time", "editing time", "editing user", "create by user id" etc. I'm using this table because there was a dynamic php script that generate it automatically. But, when i have a huge number of record ( 15k in this case ) the query getting very very very slow, and take "minutes" to do his job! But i'm not selecting all 15k records, i'm limiting to select 10 records at all! A simple query:

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

How can i run this query differently but more efficiently ?

Here the table structure:

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;

Your data is not particularly big. Here is the query:

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;

You can improve performance of this query with indexes. The two that come to mind are zd_products(title, id) and zd_tables_data_info(targetid, table_name) . Try these and see if they help. You can create these indexes either in the create table statement (or alter table ) or by using:

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);

If not, put explain in front of your query and then edit your question with the resulting plan.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM