需要连接2个超过200K数据的表。如何准备查询?

发布于 2024-12-12 05:43:13 字数 1456 浏览 0 评论 0原文

我必须连接 2 个表,每个表当前保存超过 200K 的数据。我有成员和订单表。我想要获得没有订购任何东西的会员。

我尝试了以下 SQL 查询;

结构(仅列出我需要的内容)

ORDERS                  MEMBERS
id                      id
member_id               fullName
                        email
                        landLine
                        cellPhone

查询1

$sql  = 'SELECT '.PREFIX.'members.fullName
           , '.PREFIX.'members.email
           , '.PREFIX.'members.landLine
           , '.PREFIX.'members.cellPhone, ';
$sql .= 'FROM '.PREFIX.'members';
$sql .= 'LEFT JOIN ';
$sql .= PREFIX.'orders';
$sql .= ' ON ';
$sql .= PREFIX.'members.id = '.PREFIX.'orders.member_id';
$sql .= ' WHERE '.PREFIX.'orders.member_id IS NULL LIMIT 50';

查询2

$sql2  = 'select id, fullName, email, landLine, cellphone 
          from '.PREFIX.'members 
          where '.PREFIX.'members.id not in 
             (select member_id from '.PREFIX.'orders) 
          LIMIT 50';

查询3

$sql3  = 'select id, fullName, email, landLine, cellphone 
          from '.PREFIX.'members m 
          where not exists 
            (select null from '.PREFIX.'orders o where s.members_id = o.id) 
          LIMIT 50';

到目前为止,所有3个查询都不起作用。一分多钟过去了,我还在等待结果。

最优雅的方法是什么?哪一个更快并且使用更少的资源?我在这里没有看到任何错误,为什么它会起作用,但由于某种原因它无法列出。

提前感谢您的帮助。

I have to join 2 tables which are currently holding more than 200K data each. I have members and orders table. I would like to get members who didn't order anything.

I tried following SQL queries;

Structure (just listing what I need)

ORDERS                  MEMBERS
id                      id
member_id               fullName
                        email
                        landLine
                        cellPhone

Query1

$sql  = 'SELECT '.PREFIX.'members.fullName
           , '.PREFIX.'members.email
           , '.PREFIX.'members.landLine
           , '.PREFIX.'members.cellPhone, ';
$sql .= 'FROM '.PREFIX.'members';
$sql .= 'LEFT JOIN ';
$sql .= PREFIX.'orders';
$sql .= ' ON ';
$sql .= PREFIX.'members.id = '.PREFIX.'orders.member_id';
$sql .= ' WHERE '.PREFIX.'orders.member_id IS NULL LIMIT 50';

Query 2

$sql2  = 'select id, fullName, email, landLine, cellphone 
          from '.PREFIX.'members 
          where '.PREFIX.'members.id not in 
             (select member_id from '.PREFIX.'orders) 
          LIMIT 50';

Query 3

$sql3  = 'select id, fullName, email, landLine, cellphone 
          from '.PREFIX.'members m 
          where not exists 
            (select null from '.PREFIX.'orders o where s.members_id = o.id) 
          LIMIT 50';

All 3 queries so far didn't work. More than a minute passed, I am still waiting for the results.

What is the most elegant way to do this? Which one is faster and using less resources? I don't see anything wrong here why it would work but for some reason it just can't list.

Thank you for your help in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

白芷 2024-12-19 05:43:13

如果您在没有空格的情况下执行SELECT a,b FROM cLEFT JOIN d,则查询将永远无法工作。否则查询 1 应该没问题,并且在我看来这是更好的表达方式。

至于性能,你应该按照 Marco 的建议放置索引。优化器应该足够聪明,能够为所有三个查询发出相同的计划。

a query will never work if you do SELECT a,b FROM cLEFT JOIN d without space. Otherwise query 1 should be fine and is in my opinion the better way to express it.

As for performance you should put indexes as Marco suggested. The optimizer should be smart enough to issue the same plan for all three queries.

花开半夏魅人心 2024-12-19 05:43:13

我应该尝试

SELECT id, fullName, email, landLine, cellphone 
FROM members
WHERE id NOT IN
    (SELECT DISTINCT member_id FROM orders)
LIMIT 50

确保在 members.idorders.member_id 上建立索引。

I should try

SELECT id, fullName, email, landLine, cellphone 
FROM members
WHERE id NOT IN
    (SELECT DISTINCT member_id FROM orders)
LIMIT 50

Be sure to put indexes on members.id and orders.member_id.

以为你会在 2024-12-19 05:43:13

好吧,就在这里。删除最后的“IS NULL”部分,以便您可以看到到底发生了什么;当你看到它时,它非常简单 =-)

select * from Members left join orders on Members.id=orders.member_id WHERE member_id IS NULL;

注意:我认为你应该更改你的 'id 的名称将订单表中的“order_id”列更改为“order_id”,将会员表中的“id”列更改为“member_id”,以避免很多混乱。另外不要忘记添加索引。

我使用你的表结构和我自己的值对其进行了测试。它返回迈克尔·乔丹和巴拉克·奥巴马,因为他们没有任何订单。

INSERT INTO orders (id, member_id) VALUES ('aa', '1');
INSERT INTO orders (id, member_id) VALUES ('bb', '1');
INSERT INTO orders (id, member_id) VALUES ('cc', '1');
INSERT INTO orders (id, member_id) VALUES ('dd', '1');
INSERT INTO orders (id, member_id) VALUES ('gg', '2');
INSERT INTO orders (id, member_id) VALUES ('hh', '2');
INSERT INTO orders (id, member_id) VALUES ('ii', '2');
INSERT INTO orders (id, member_id) VALUES ('xx', '3');
INSERT INTO orders (id, member_id) VALUES ('yy', '3');
INSERT INTO orders (id, member_id) VALUES ('zz', '3');

INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('1', 'John smith', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('2', 'Person B', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('3', 'Tom Brady', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('4', 'Michael Jordan', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('5', 'Barack Obama', '[email protected]', '1234567890', '1234567890');

Alright here it is. Remove the 'IS NULL' part at the end so you can see what is really going on; it's pretty simple when you see it =-)

select * from members left join orders on members.id=orders.member_id WHERE member_id IS NULL;

Note: I think you should change the name of your 'id' column to 'order_id' in the orders table and the 'id' column in the members table to 'member_id' to avoid a lot of confusion. Also don't forget to add indexes.

I tested it using your table structure and my own values. It returns Michael Jordan and Barack Obama because they did not have any orders.

INSERT INTO orders (id, member_id) VALUES ('aa', '1');
INSERT INTO orders (id, member_id) VALUES ('bb', '1');
INSERT INTO orders (id, member_id) VALUES ('cc', '1');
INSERT INTO orders (id, member_id) VALUES ('dd', '1');
INSERT INTO orders (id, member_id) VALUES ('gg', '2');
INSERT INTO orders (id, member_id) VALUES ('hh', '2');
INSERT INTO orders (id, member_id) VALUES ('ii', '2');
INSERT INTO orders (id, member_id) VALUES ('xx', '3');
INSERT INTO orders (id, member_id) VALUES ('yy', '3');
INSERT INTO orders (id, member_id) VALUES ('zz', '3');

INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('1', 'John smith', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('2', 'Person B', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('3', 'Tom Brady', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('4', 'Michael Jordan', '[email protected]', '1234567890', '1234567890');
INSERT INTO members (id, fullName, email, landLine, cellPhone) VALUES ('5', 'Barack Obama', '[email protected]', '1234567890', '1234567890');
笑叹一世浮沉 2024-12-19 05:43:13

首先确保您正在使用的所有列都有索引。

您想要做的是对成员的 ID 和订单进行左连接,并且每当成员在 ID 列中具有空值时,它们就不存在于其他表中。在 PHP 中执行查询之前,请先在 MySQL 工作台中测试查询,以便您可以了解发生了什么。

如果您向我展示您的表结构,我将为您写出一个有效的查询。

First off make sure you have indexes on all of the columns you are using.

What you want to do is a left join on the member's ID and order's and whenever a member has a null value in the ID column they did not exist in the other table. Test the query in the MySQL workbench first before you do it in PHP, so you can see what is happening.

If you show me your table structures I'll write out a working query for you.

梦途 2024-12-19 05:43:13

您的第一个查询似乎没问题。

确保:

1) orders.member_idmembers.id 的 fk
2)在orders.member_idmembers.id上有一个索引

我还建议您直接在mysql客户端上运行查询并在那里优化它,然后尝试从php。至少你会确保,在优化时,mysql不是瓶颈,而是其他东西。

Your 1st query seems to be ok.

Make sure:

1) that orders.member_id is an fk to members.id
2) there is an index on orders.member_id and members.id

I also suggest that you run your query directly on mysql client and optimize it there, then try from php. At least you will make sure, when optimized, that mysql is not the bottleneck, but something else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文