简体   繁体   English

更好的性能,JOIN 还是多个查询?

[英]Better performance, JOIN or multiple queries?

Whats the best way to achieve best performance for getting data from multiple table?从多个表中获取数据的最佳性能是什么?

I have these following tables我有这些下表

Applicants ( 50,101 rows )
-id
-first_name
-email

Phones ( 50,151 rows )
-id
-number
-model_id
-model_type

Address (100,263 rows)
-id
-state
-model_id
-model_type

Business (26 rows)
-id
-company
-model_id
-model_type

My desired result我想要的结果

 id | first_name | email | number | company | state
----+------------+-------+--------+---------+------
  1 |    test    |   -   |   -    |    -    |   -

Im using SQLyog to perform this query below and its very slow, I have thousands of data on these tables我使用SQLyog在下面执行这个查询,而且速度很慢,我在这些表上有成千上万的数据

SELECT `app`.`id`,`app`.`first_name`, `app`.`email`, `p`.`number`, `b`.`company`, `add`.`state`
FROM `applicants` AS `app`
LEFT JOIN  phones AS `p` ON `app`.`id` = `p`.`model_id` 
    AND `p`.`model_type` = 'App\\Models\\Applicant'
LEFT JOIN `businesses` AS `b` ON `app`.`id` = `b`.`model_id` 
    AND `b`.`model_type` = 'App\\Models\\Applicant'
LEFT JOIN `addresses` AS `add` ON `app`.`id` = `add`.`model_id` 
    AND `b`.`model_type` = 'App\\Models\\Applicant'
LIMIT 10

summary, takes 25.794 to finish总结,需要 25.794 才能完成

Execution Time : 25.792 sec
Transfer Time  : 0.001 sec
Total Time     : 25.794 sec

What would be the best way to achieve my goal?实现我的目标的最佳方式是什么? like should a perform a separate multiple query for each phone, business and address?比如应该对每个电话、公司和地址执行单独的多个查询吗? though Im not sure how to achieve my desired result with multiple query虽然我不确定如何通过多个查询达到我想要的结果

It really depends on the specific situation what will be faster.这真的取决于具体情况,什么会更快。 Also you can probably optimize your situation by creating the proper indexes.您也可以通过创建适当的索引来优化您的情况。 For example if you query a lot by model_id and model_type , you could create an index on either, or both of the fields.例如,如果您通过model_idmodel_type查询很多,您可以在其中一个或两个字段上创建索引。

I would suggest running the query with joins with an EXPLAIN in front, ie EXPLAIN SELECT {your query} .我建议使用前面带有EXPLAIN连接运行查询,即EXPLAIN SELECT {your query} That will give you some insights on how MySQL executes your query.这会给你一些关于 MySQL 如何执行你的查询的见解。 Then you can try the same with separate queries.然后,您可以尝试使用单独的查询进行相同的操作。 Then add indexes and see if they are used.然后添加索引,看看它们是否被使用。 Then choose the best performing solution.然后选择性能最佳的解决方案。

About indexes:关于索引:

Introduction: https://www.mysqltutorial.org/mysql-index/mysql-create-index/简介: https : //www.mysqltutorial.org/mysql-index/mysql-create-index/

More in-depth: https://use-the-index-luke.com/更深入: https : //use-the-index-luke.com/

From my understanding, there is no general answer on this question.根据我的理解,这个问题没有统一的答案。 One of the possible solutions is denormalisation.一种可能的解决方案是非规范化。 Creating extra table with all the data you need periodically.定期使用您需要的所有数据创建额外的表。 It helps a lot in some cases but, unfortunately, just not possible to do this way in other cases.在某些情况下它有很大帮助,但不幸的是,在其他情况下不可能这样做。

Here are the things to think about in this case.以下是在这种情况下需要考虑的事情。 Arguments for a single query:单个查询的参数:

  • Databases are designed to handle complicated queries, so the JOIN s are probably faster in the database.数据库旨在处理复杂的查询,因此数据库中的JOIN可能更快。
  • Each query incurs overhead for moving the query into the database and data out of the database.每个查询都会产生将查询移入数据库并将数据移出数据库的开销。

In favor of a multiple queries:支持多个查询:

  • Query optimizers are not perfect, so they might come up with the wrong plan.查询优化器并不完美,因此它们可能会提出错误的计划。
  • Returning data as a single result set often requires a "wide" format for the data with many repeated columns.将数据作为单个结果集返回通常需要具有许多重复列的数据的“宽”格式。 Returning more data is slower.返回更多数据会更慢。

In general, the balance is on the single query, but that is not always true.一般来说,平衡是在单个查询上,但并不总是如此。 For instance, if the database is fast but the bandwidth to the application is slow, the last bullet may consistently be the dominating factor.例如,如果数据库速度很快但应用程序的带宽很慢,那么最后一项可能始终是主导因素。

I am surprised that your query takes so much time.我很惊讶您的查询需要这么多时间。 You don't have an ORDER BY or GROUP BY so the time to the first result should be pretty fast.您没有ORDER BYGROUP BY因此获得第一个结果的时间应该非常快。 You might be able to have it run faster by simply doing a subselect on app :您可以通过简单地在app上执行子选择来让它运行得更快:

FROM (SELECT app.* 
      FROM `applicants` `app`
      LIMIT 10
     ) app . . . 

Joining tables is taking all of the data from each table and combining it into one.联接表是将每个表中的所有数据合并为一个。 It is expected to have a slower loading time because of this.因此,预计加载时间会更慢。 If you are only gathering specific data from each table then running seperate queries might be the better idea.如果您只从每个表中收集特定数据,那么运行单独的查询可能是更好的主意。 It depends on how your application is laid out and how you are using this information.这取决于您的应用程序的布局方式以及您如何使用这些信息。

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

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