首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用4个联接优化MySQL查询

使用4个联接优化MySQL查询
EN

Stack Overflow用户
提问于 2017-03-16 12:54:17
回答 2查看 47关注 0票数 0

我需要尽可能地优化MySQL查询,因为当前数据库正在崩溃。我们有5张桌子:

  • 订单-包含约20万条记录
  • 语言-包含2-5
  • records order_product -包含超过20万条记录
  • 产品-包含少于100条记录
  • 通讯-包含超过5万条记录

当我们试图在电子邮件中加入时事通讯表时,的事情就开始出错了.

以下是每个表的创建:

代码语言:javascript
复制
CREATE TABLE `order` (
 `order_id` int(11) NOT NULL AUTO_INCREMENT,
 `order_id_copy` varchar(32) COLLATE utf8_bin NOT NULL,
 `invoice_no` int(11) NOT NULL DEFAULT '0',
 `invoice_prefix` varchar(26) COLLATE utf8_bin NOT NULL,
 `store_id` int(11) NOT NULL DEFAULT '0',
 `store_name` varchar(64) COLLATE utf8_bin NOT NULL,
 `store_url` varchar(255) COLLATE utf8_bin NOT NULL,
 `customer_id` int(11) NOT NULL DEFAULT '0',
 `customer_group_id` int(11) NOT NULL DEFAULT '0',
 `firstname` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
 `lastname` varchar(32) COLLATE utf8_bin NOT NULL,
 `email` varchar(96) COLLATE utf8_bin NOT NULL,
 `telephone` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
 `fax` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
 `payment_firstname` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
 `payment_lastname` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
 `payment_company` varchar(32) COLLATE utf8_bin NOT NULL,
 `payment_company_id` varchar(32) COLLATE utf8_bin NOT NULL,
 `payment_tax_id` varchar(32) COLLATE utf8_bin NOT NULL,
 `payment_address_1` varchar(128) COLLATE utf8_bin NOT NULL,
 `payment_address_2` varchar(128) COLLATE utf8_bin NOT NULL,
 `payment_city` varchar(128) COLLATE utf8_bin NOT NULL,
 `payment_postcode` varchar(10) COLLATE utf8_bin NOT NULL DEFAULT '',
 `payment_country` varchar(128) COLLATE utf8_bin NOT NULL,
 `payment_country_id` int(11) NOT NULL,
 `payment_zone` varchar(128) COLLATE utf8_bin NOT NULL,
 `payment_zone_id` int(11) NOT NULL,
 `payment_address_format` text COLLATE utf8_bin NOT NULL,
 `payment_method` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
 `payment_code` varchar(128) COLLATE utf8_bin NOT NULL,
 `shipping_firstname` varchar(32) COLLATE utf8_bin NOT NULL,
 `shipping_lastname` varchar(32) COLLATE utf8_bin NOT NULL DEFAULT '',
 `shipping_company` varchar(32) COLLATE utf8_bin NOT NULL,
 `shipping_address_1` varchar(128) COLLATE utf8_bin NOT NULL,
 `shipping_address_2` varchar(128) COLLATE utf8_bin NOT NULL,
 `shipping_city` varchar(128) COLLATE utf8_bin NOT NULL,
 `shipping_postcode` varchar(10) COLLATE utf8_bin NOT NULL DEFAULT '',
 `shipping_country` varchar(128) COLLATE utf8_bin NOT NULL,
 `shipping_country_id` int(11) NOT NULL,
 `shipping_zone` varchar(128) COLLATE utf8_bin NOT NULL,
 `shipping_zone_id` int(11) NOT NULL,
 `shipping_address_format` text COLLATE utf8_bin NOT NULL,
 `shipping_method` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
 `shipping_code` varchar(128) COLLATE utf8_bin NOT NULL,
 `comment` text COLLATE utf8_bin NOT NULL,
 `total` decimal(15,4) NOT NULL DEFAULT '0.0000',
 `order_status_id` int(11) NOT NULL DEFAULT '0',
 `affiliate_id` int(11) NOT NULL,
 `commission` decimal(15,4) NOT NULL,
 `language_id` int(11) NOT NULL,
 `currency_id` int(11) NOT NULL,
 `currency_code` varchar(3) COLLATE utf8_bin NOT NULL,
 `currency_value` decimal(15,8) NOT NULL DEFAULT '1.00000000',
 `ip` varchar(15) COLLATE utf8_bin NOT NULL,
 `forwarded_ip` varchar(15) COLLATE utf8_bin NOT NULL,
 `user_agent` varchar(255) COLLATE utf8_bin NOT NULL,
 `accept_language` varchar(255) COLLATE utf8_bin NOT NULL,
 `date_added` datetime NOT NULL,
 `date_modified` datetime NOT NULL,
 `newsletter` tinyint(1) NOT NULL DEFAULT '0',
 PRIMARY KEY (`order_id`),
 KEY `date_added` (`date_added`),
 KEY `date_modified` (`date_modified`),
 KEY `date_added_2` (`date_added`),
 KEY `store_id` (`store_id`),
 KEY `customer_id` (`customer_id`),
 KEY `customer_group_id` (`customer_group_id`),
 KEY `payment_company_id` (`payment_company_id`),
 KEY `payment_tax_id` (`payment_tax_id`),
 KEY `payment_country_id` (`payment_country_id`),
 KEY `payment_zone_id` (`payment_zone_id`),
 KEY `shipping_country_id` (`shipping_country_id`),
 KEY `shipping_zone_id` (`shipping_zone_id`),
 KEY `order_status_id` (`order_status_id`),
 KEY `affiliate_id` (`affiliate_id`),
 KEY `language_id` (`language_id`),
 KEY `currency_id` (`currency_id`)
) ENGINE=MyISAM AUTO_INCREMENT=421544 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

CREATE TABLE `language` (
 `language_id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(32) NOT NULL,
 `code` varchar(5) NOT NULL,
 `locale` varchar(255) NOT NULL,
 `image` varchar(64) NOT NULL,
 `directory` varchar(32) NOT NULL,
 `filename` varchar(64) NOT NULL,
 `sort_order` int(3) NOT NULL DEFAULT '0',
 `status` tinyint(1) NOT NULL,
 PRIMARY KEY (`language_id`),
 KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

CREATE TABLE `order_product` (
 `order_product_id` int(11) NOT NULL AUTO_INCREMENT,
 `order_id` int(11) NOT NULL,
 `product_id` int(11) NOT NULL,
 `name` varchar(255) COLLATE utf8_bin NOT NULL,
 `model` varchar(24) COLLATE utf8_bin NOT NULL,
 `quantity` int(4) NOT NULL,
 `price` decimal(15,4) NOT NULL DEFAULT '0.0000',
 `total` decimal(15,4) NOT NULL DEFAULT '0.0000',
 `tax` decimal(15,4) NOT NULL DEFAULT '0.0000',
 `discount` decimal(15,4) NOT NULL,
 `discount_tax` decimal(15,4) NOT NULL,
 `reward` int(8) NOT NULL,
 PRIMARY KEY (`order_product_id`),
 KEY `order_id` (`order_id`),
 KEY `product_id` (`product_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1243823 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

CREATE TABLE `product` (
 `product_id` int(11) NOT NULL AUTO_INCREMENT,
 `model` varchar(64) NOT NULL,
 `sku` varchar(64) NOT NULL,
 `upc` varchar(12) NOT NULL,
 `ean` varchar(14) NOT NULL,
 `jan` varchar(13) NOT NULL,
 `isbn` varchar(13) NOT NULL,
 `mpn` varchar(64) NOT NULL,
 `location` varchar(128) NOT NULL,
 `quantity` int(4) NOT NULL DEFAULT '0',
 `stock_status_id` int(11) NOT NULL,
 `image` varchar(255) DEFAULT NULL,
 `manufacturer_id` int(11) NOT NULL,
 `shipping` tinyint(1) NOT NULL DEFAULT '1',
 `price` decimal(15,4) NOT NULL DEFAULT '0.0000',
 `points` int(8) NOT NULL DEFAULT '0',
 `tax_class_id` int(11) NOT NULL,
 `date_available` date NOT NULL,
 `weight` decimal(15,8) NOT NULL DEFAULT '0.00000000',
 `weight_class_id` int(11) NOT NULL DEFAULT '0',
 `length` decimal(15,8) NOT NULL DEFAULT '0.00000000',
 `width` decimal(15,8) NOT NULL DEFAULT '0.00000000',
 `height` decimal(15,8) NOT NULL DEFAULT '0.00000000',
 `length_class_id` int(11) NOT NULL DEFAULT '0',
 `subtract` tinyint(1) NOT NULL DEFAULT '1',
 `minimum` int(11) NOT NULL DEFAULT '1',
 `sort_order` int(11) NOT NULL DEFAULT '0',
 `status` tinyint(1) NOT NULL DEFAULT '0',
 `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `date_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `viewed` int(5) NOT NULL DEFAULT '0',
 PRIMARY KEY (`product_id`),
 KEY `model` (`model`),
 KEY `stock_status_id` (`stock_status_id`),
 KEY `manufacturer_id` (`manufacturer_id`),
 KEY `tax_class_id` (`tax_class_id`),
 KEY `weight_class_id` (`weight_class_id`),
 KEY `length_class_id` (`length_class_id`)
) ENGINE=MyISAM AUTO_INCREMENT=135 DEFAULT CHARSET=utf8

CREATE TABLE `newsletter` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `email` varchar(254) NOT NULL,
 `agreed` tinyint(1) NOT NULL DEFAULT '0',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8

下面是SQL:

代码语言:javascript
复制
SELECT o.order_id,
       o.firstname,
       o.lastname,
       o.email,
       o.telephone,
       LOWER(l.code) AS language_code,
       o.currency_code,
       o.total,
       o.date_added,
       o.order_status_id,
       op.product_id,
       p.sku,
       op.price,
       op.model,
       op.name,
       op.tax,
       nl.agreed
FROM `order` o
JOIN LANGUAGE l ON l.language_id = o.language_id
LEFT JOIN order_product op ON op.order_id = o.order_id
LEFT JOIN product p ON p.product_id = op.product_id
LEFT JOIN newsletter nl ON nl.email = o.email
WHERE o.order_status_id IN(3,
                           5)
  AND o.order_id > '0'
ORDER BY o.order_id ASC
LIMIT 1

我们不知道如何优化SQL,即使我们只限制了1。

EN

回答 2

Stack Overflow用户

发布于 2017-03-16 13:01:23

我个人试图避免加入伐查。也就是说,如果不能改进设计,可以考虑在电子邮件列中添加索引,这至少会提高搜索性能。

希望这有帮助

票数 0
EN

Stack Overflow用户

发布于 2017-03-16 13:09:13

如果查询很长-我会尝试添加索引(order_id,order_status_id) +可能重写ORDER

由o.order_id,order_status_id订购

在这种情况下,查询应该立即完成。

如果仍然没有成功--您可以尝试先选择单个订单,然后将其余的表加入到该行中。

(啊,既然您正在使用myisam -确保其他查询不会影响执行时间,例如空闲服务器上的基准测试)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42834706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档