简体   繁体   English

如何通过多个连接加速 MYSQL 查询?

[英]How to speed up MYSQL query with multiple joins?

looking for help to speed up this query:寻求帮助以加快此查询:

SELECT tickets.ticketid, datenew, products.name 
FROM tickets 
INNER JOIN ticketlines ON tickets.id = ticketlines.ticket 
INNER JOIN products ON ticketlines.product = products.id 
INNER JOIN receipts ON receipts.id = tickets.id 
WHERE (category !='feb765ef-c8a8-4fa2-969c-90f67fe6b3be' AND category!='888f4893-f300-43b5-9933-d549ade744e0' AND category !='8f2031e8-64a4-4abf-8175-3d2bedd9f950' AND category !='ca370ced-1c3b-434c-905e-ec1bc709543b' AND category !='f92ff0ac-fa11-4a5f-a3dd-e0d9ed9c171a' AND category !='445e8605-1cd9-4714-b3fd-7389ac29c206' and category !='05143c54-8a7e-4ce2-97cc-f84f9cf41395' AND category !='8c78afea-b9e2-44cf-b497-c384045b3202' AND category !='95919f7f-ff2e-4aa1-8110-ef63c022c01b' AND category !='f4f88b05-38a1-4956-9182-4c04a0808df7') AND datedone IS NULL 
ORDER BY ticketid

This is from a cash register database that I am using to pull data for order display.这是我用来提取订单显示数据的收银机数据库。 The structure is the receipt has the primary id, the timein and timedone(DATEDONE) timestamps.结构是收据具有主 ID、timein 和 timedone(DATEDONE) 时间戳。 The ticket table has ticket id which is the same as receipt id.票证表的票证 ID 与收据 ID 相同。 Ticketlines table is the line items on the receipt/ticket. Ticketlines 表是收据/票上的行项目。 And then Products table has the human readable definitions of the products.然后 Products 表具有产品的人类可读定义。

The query is to pull all items that aren't completed, ie DATEDONE is null, and display the items that were ordered.查询是拉取所有未完成的项目,即DATEDONE为null,并显示已订购的项目。

Ticket and Receipt tables have 15K rows, Ticketlines has ~20K rows, Products has 1.5k. Ticket 和 Receipt 表有 15K 行,Ticketlines 有大约 20K 行,Products 有 1500 行。

Pretty small data.相当小的数据。 But this query takes over 20 seconds.但是这个查询需要超过 20 秒。 I think since I am using primary key IDs for everything, I don't need to index anything, but I am a total noob, so I'm happy to be told I'm wrong.我想因为我对所有东西都使用主键 ID,所以我不需要索引任何东西,但我是一个完全的菜鸟,所以我很高兴被告知我错了。 I'll appreciate any help and can provide any further details.我将不胜感激任何帮助,并可以提供任何进一步的细节。 Thanks!谢谢!

EDIT:编辑:

per comments, I am showing table structures.根据评论,我正在展示表结构。 I'm sorry for the formatting nightmare, I'm unfamiliar with this platform and unsure how to make it more readable:-(对于格式化噩梦,我很抱歉,我不熟悉这个平台并且不确定如何使其更具可读性:-(

| receipts | CREATE TABLE `receipts` (
  `ID` varchar(255) NOT NULL,
  `MONEY` varchar(255) NOT NULL,
  `DATENEW` datetime NOT NULL,
  `ATTRIBUTES` mediumblob,
  `PERSON` varchar(255) DEFAULT NULL,
  `DATEDONE` datetime DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `RECEIPTS_FK_MONEY` (`MONEY`),
  KEY `RECEIPTS_INX_1` (`DATENEW`),
  CONSTRAINT `RECEIPTS_FK_MONEY` FOREIGN KEY (`MONEY`) REFERENCES `closedcash` (`MONEY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |


| tickets | CREATE TABLE `tickets` (
  `ID` varchar(255) NOT NULL,
  `TICKETTYPE` int(11) NOT NULL DEFAULT '0',
  `TICKETID` int(11) NOT NULL,
  `PERSON` varchar(255) NOT NULL,
  `CUSTOMER` varchar(255) DEFAULT NULL,
  `STATUS` int(11) NOT NULL DEFAULT '0',
  `DONE` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `TICKETS_FK_2` (`PERSON`),
  KEY `TICKETS_CUSTOMERS_FK` (`CUSTOMER`),
  KEY `TICKETS_TICKETID` (`TICKETTYPE`,`TICKETID`),
  CONSTRAINT `TICKETS_CUSTOMERS_FK` FOREIGN KEY (`CUSTOMER`) REFERENCES `customers` (`ID`),
  CONSTRAINT `TICKETS_FK_2` FOREIGN KEY (`PERSON`) REFERENCES `people` (`ID`),
  CONSTRAINT `TICKETS_FK_ID` FOREIGN KEY (`ID`) REFERENCES `receipts` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |


| ticketlines | CREATE TABLE `ticketlines` (
  `TICKET` varchar(255) NOT NULL,
  `LINE` int(11) NOT NULL,
  `PRODUCT` varchar(255) DEFAULT NULL,
  `ATTRIBUTESETINSTANCE_ID` varchar(255) DEFAULT NULL,
  `UNITS` double NOT NULL,
  `PRICE` double NOT NULL,
  `TAXID` varchar(255) NOT NULL,
  `ATTRIBUTES` mediumblob,
  PRIMARY KEY (`TICKET`,`LINE`),
  KEY `TICKETLINES_FK_2` (`PRODUCT`),
  KEY `TICKETLINES_ATTSETINST` (`ATTRIBUTESETINSTANCE_ID`),
  KEY `TICKETLINES_FK_3` (`TAXID`),
  CONSTRAINT `TICKETLINES_ATTSETINST` FOREIGN KEY (`ATTRIBUTESETINSTANCE_ID`) REFERENCES `attributesetinstance` (`ID`),
  CONSTRAINT `TICKETLINES_FK_2` FOREIGN KEY (`PRODUCT`) REFERENCES `products` (`ID`),
  CONSTRAINT `TICKETLINES_FK_3` FOREIGN KEY (`TAXID`) REFERENCES `taxes` (`ID`),
  CONSTRAINT `TICKETLINES_FK_TICKET` FOREIGN KEY (`TICKET`) REFERENCES `tickets` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

| products | CREATE TABLE `products` (
  `ID` varchar(255) NOT NULL,
  `REFERENCE` varchar(255) NOT NULL,
  `CODE` varchar(255) NOT NULL,
  `CODETYPE` varchar(255) DEFAULT NULL,
  `NAME` varchar(255) NOT NULL,
  `PRICEBUY` double NOT NULL,
  `PRICESELL` double NOT NULL,
  `CATEGORY` varchar(255) NOT NULL,
  `TAXCAT` varchar(255) NOT NULL,
  `ATTRIBUTESET_ID` varchar(255) DEFAULT NULL,
  `STOCKCOST` double DEFAULT NULL,
  `STOCKVOLUME` double DEFAULT NULL,
  `IMAGE` mediumblob,
  `ISCOM` bit(1) NOT NULL DEFAULT b'0',
  `ISSCALE` bit(1) NOT NULL DEFAULT b'0',
  `ISKITCHEN` bit(1) NOT NULL DEFAULT b'0',
  `PRINTKB` bit(1) NOT NULL DEFAULT b'0',
  `SENDSTATUS` bit(1) NOT NULL DEFAULT b'0',
  `ISSERVICE` bit(1) NOT NULL DEFAULT b'0',
  `ATTRIBUTES` mediumblob,
  `DISPLAY` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `PRODUCTS_INX_0` (`REFERENCE`),
  UNIQUE KEY `PRODUCTS_INX_1` (`CODE`),
  UNIQUE KEY `PRODUCTS_NAME_INX` (`NAME`),
  KEY `PRODUCTS_FK_1` (`CATEGORY`),
  KEY `PRODUCTS_TAXCAT_FK` (`TAXCAT`),
  KEY `PRODUCTS_ATTRSET_FK` (`ATTRIBUTESET_ID`),
  CONSTRAINT `PRODUCTS_ATTRSET_FK` FOREIGN KEY (`ATTRIBUTESET_ID`) REFERENCES `attributeset` (`ID`),
  CONSTRAINT `PRODUCTS_FK_1` FOREIGN KEY (`CATEGORY`) REFERENCES `categories` (`ID`),
  CONSTRAINT `PRODUCTS_TAXCAT_FK` FOREIGN KEY (`TAXCAT`) REFERENCES `taxcategories` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

Also, here is EXPLAIN output:此外,这里是 EXPLAIN output:

| id | select_type | table       | partitions | type   | possible_keys            | key     | key_len | ref                                | rows  | filtered | Extra                                        |
+----+-------------+-------------+------------+--------+--------------------------+---------+---------+------------------------------------+-------+----------+----------------------------------------------+
|  1 | SIMPLE      | receipts    | NULL       | ALL    | PRIMARY                  | NULL    | NULL    | NULL                               | 14624 |    10.00 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | tickets     | NULL       | eq_ref | PRIMARY                  | PRIMARY | 767     | receipts.ID         |     1 |   100.00 | NULL                                         |
|  1 | SIMPLE      | ticketlines | NULL       | ref    | PRIMARY,TICKETLINES_FK_2 | PRIMARY | 767     | receipts.ID         |     1 |   100.00 | Using where                                  |
|  1 | SIMPLE      | products    | NULL       | eq_ref | PRIMARY,PRODUCTS_FK_1    | PRIMARY | 767     | ticketlines.PRODUCT |     1 |    97.97 | Using where                                  |
+----+-------------+-------------+------------+--------+--------------------------+---------+---------+------------------------------------+-------+----------+----------------------------------------------+
4 rows in set, 1 warning (0.04 sec)

Try changing data types of all columns to the minimal required ones.尝试将所有列的数据类型更改为所需的最少类型。 Add indexes on columns in WHERE.在 WHERE 中的列上添加索引。 Add index on ticketlines.ticket.在 ticketlines.ticket 上添加索引。

I ended up deleted 10K rows from every linked table and it queries running in.2 seconds now.我最终从每个链接表中删除了 10K 行,现在查询运行时间为 2 秒。 I guess absent any more advice, i will be doing annual cleanup of old tickets.我想如果没有更多建议,我将每年清理一次旧票。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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