如果我说:
Table1 left join Table2
Run Code Online (Sandbox Code Playgroud)
和说一样吗?:
Table2 right join Table1
Run Code Online (Sandbox Code Playgroud)
换句话说,我是否应该期望从 2 个相同的查询中获得相同的结果,其中唯一改变的是首先写入哪个表以及是使用左连接还是右连接(遵循我上面描述的相同模式?)
ypercube 解决了这个问题。子查询是完全没有必要的,整个事情都可以使用普通连接。不过,MySQL 的优化器无法使用我的原始查询仍然很奇怪。有关问题和许多详细信息,请参见下文。在我的问题底部加上一个完整的解决方案。它基于 ypercube 的答案。
每个子查询都非常快,不到 1 秒。加入了 5-6 个子查询(一些LEFT,一些INNER),时间增加到 400 秒。
我用于测试的整体查询仅返回 441 行。
我尝试将每个子查询放在“CREATE TABLE”查询中。每一个都在不到 1 秒的时间内完成。然后我使用那些新创建的表重新执行外部查询,它的运行时间也远低于 1 秒。所以连接没有实际问题。我id为我创建的表添加了索引。所有表都在匹配id= 上连接id。
如何让 MySQL 高效地执行查询?我必须使用临时表吗?我已经编写了一堆 PHP 代码来将多个子查询连接放在一起,所以如果可能的话,我宁愿弄清楚如何使其工作。
我尝试使用“STRAIGHT_JOIN”关键字并删除外部ORDER BY. 这将查询时间减少到 90 秒。但我应该最多获得 1 秒。
我试过STRAIGHT_JOIN了ORDER BY,花了 235 秒。所以看起来外部ORDER BY是一个主要的性能问题。
编辑:
使用临时表进行测试。查询运行速度非常快。但是必须有一种方法可以让 mysql 使用 JOINS 快速完成它。
此外,慢查询日志显示:
Rows_examined: 484006914
Run Code Online (Sandbox Code Playgroud)
4.84 亿行看起来像笛卡尔积。为什么要检查这么多行?
查询具有以下结构:
SELECT t0.`id`, t1.`length`, t2.`height`, t3.`family`
FROM
`products` t0
INNER JOIN
( …Run Code Online (Sandbox Code Playgroud) 当我尝试更新连接时,我收到“ORA-01779:无法修改映射到非键保留表的列”。我在网站上搜索并找到了很多关于保留密钥的含义以及为什么有必要的建议......但据我所知,我正在遵守该建议,但仍然出现错误。
我有两个表:
PG_LABLOCATION has, among other things, the columns:
"LABLOCID" NUMBER,
"DNSNAME" VARCHAR2(200 BYTE)
LABLOCID is the primary key, DNSNAME has a unique constraint
PG_MACHINE has, among other things, the columns:
"MACHINEID" NUMBER,
"LABLOCID" NUMBER,
"IN_USE" NUMBER(1,0) DEFAULT 0,
"UPDATE_TIME" TIMESTAMP (6) DEFAULT '01-JAN-1970'
MACHINEID is a primary key
LABLOCID is a foreign key into LABLOCID in PG_LABLOCATION (its primary key)
Run Code Online (Sandbox Code Playgroud)
我正在运行的更新是:
update
(select mac.in_use, mac.update_time
from pg_machine mac
inner join pg_lablocation loc
on mac.lablocid = loc.lablocid
where loc.dnsname = …Run Code Online (Sandbox Code Playgroud) 我将 PostgreSQL 9.1 与 Ruby on Rails 应用程序一起使用。
我正在尝试列出属于同一项目 ID (proj_sous_projet_id = 2) 的每个“费用”(在我的历史表中:hist_version_charges)的最后一个版本。
这使我使用 max() 聚合函数并将结果应用于同一个表上的 JOIN 函数,因为如果 SELECT 子句中的列未出现在 GROUP BY 子句中,则 PostgreSQL 没有授权使用它们,但使用最大值() 显然我对包含最大值的行感兴趣!
这是我的查询:
SELECT h_v_charges.*,
max(last_v.version) as lv
FROM hist_versions_charges h_v_charges
JOIN hist_versions_charges last_v
ON h_v_charges.version = lv
AND h_v_charges.proj_charge_id = last_v.proj_charge_id
GROUP BY last_v.proj_sous_projet_id,
last_v.proj_charge_id
HAVING last_v.proj_sous_projet_id = 2
ORDER BY h_v_charges.proj_charge_id ASC;
Run Code Online (Sandbox Code Playgroud)
我得到的错误信息:
ERROR: column "lv" does not exist
LINE 1: ..._versions_charges last_v ON h_v_charges.version = lv AND h_v...
^
********** Error ********** …Run Code Online (Sandbox Code Playgroud) 根据文档MySQL Explain Output format,MySQL 使用嵌套循环连接方法解析所有连接。有没有办法强制 MySQL 使用散列连接?
假设我有以下查询:
SELECT *
FROM AppDetails, AppTags
WHERE AppDetails.AppID = '1'
AND AppDetails.AppID = AppTags.AppID
Run Code Online (Sandbox Code Playgroud)
这给出了以下结果:
AppID AppName AppType Tag
1 Application1 Utility Test1
1 Application1 Utility Test2
1 Application1 Utility Test3
Run Code Online (Sandbox Code Playgroud)
如何修改查询以返回如下内容:
AppID AppName AppType Tags
1 Application1 Utility Test1,Test2,Test3
Run Code Online (Sandbox Code Playgroud) MySQL 5.5.8:
问题 1:
以下陈述是否有任何不同,如果有,哪一个是首选的性能明智的?甚至可以在不知道 where 子句前后表的行数以及可能的索引用法的情况下回答这个问题吗?
SELECT *
FROM a JOIN b ON a.id = b.id AND a.col2 BETWEEN 1 AND 5;
SELECT *
FROM a JOIN b ON a.id = b.id
WHERE a.col2 BETWEEN 1 AND 5;
Run Code Online (Sandbox Code Playgroud)
我问的原因是因为例如,如果表很大,但 where 子句过滤掉了 99.9999% 的记录,如果在连接后 99.9999% 的记录没有被使用,我不想浪费时间连接大量表。
问题2:
采取相同的情况,哪个语句(如果有任何不同)需要更少的 IOPS。(索引出现在 b.id 上,一个出现在 a.col2 上)
我有一个表名“ TABLE_A ( id integer, no integer) ”。
我想用“id”和当前的“no sum of no”=以前的“no sum of no”对“no”求和
这是我的代码:
1/创建表并插入数据:
create table table_a (id int, no int);
insert into table_a values(1, 10);
insert into table_a values(1, 20);
insert into table_a values(1, 30);
insert into table_a values(2, 100);
insert into table_a values(2, 200);
insert into table_a values(2, 300);
insert into table_a values(3, 1);
insert into table_a values(3, 2);
insert into table_a values(3, 3);
insert into table_a values(3, 3);
Run Code Online (Sandbox Code Playgroud)
2/ 预期结果:
id | sum_of_no …Run Code Online (Sandbox Code Playgroud) 我正在使用 Postgres,它强制执行 SELECT...GROUP BY 中的所有列必须出现在 GROUP BY 子句中或在聚合函数中使用的约束。
假设我正在为人们的汽车建模,我想算出一个人的姓名、牌照号码以及他们拥有的汽车数量。这是我作为SQL Fiddle 的示例。
我会有以下架构:
CREATE TABLE person(
id integer PRIMARY KEY,
name text
);
CREATE TABLE license(
person_id integer REFERENCES person(id),
expiry_date date
);
CREATE TABLE car(
owner_id integer REFERENCES person(id),
registration_number TEXT
);
Run Code Online (Sandbox Code Playgroud)
这是查询:
SELECT person.name, person.id, license.expiry_date, COUNT(car) FROM person
JOIN license ON license.person_id = person.id
JOIN car ON car.owner_id = person.id
WHERE person.name = 'Charles Bannerman'
GROUP BY person.id;
Run Code Online (Sandbox Code Playgroud)
我知道,因为我自己的业务逻辑,一个人只能有一个license,所以当我加入这个人的时候,即使是GROUP BY'd,我应该可以找到他们的license number。但是,因为它不是 GROUP …
我写了这个查询:
SELECT
"BD - Utilizadores".Utilizador,
"BD - Utilizadores"."Palavra passe",
"BD - Áreas".área
FROM "BD - Utilizadores"
INNER JOIN "BD - Permissões"
on "BD - Utilizadores".id = "BD - Permissões"."user_id"
Join "BD - Áreas"
on "BD - Permissões".area_id = "BD - Áreas".id
Run Code Online (Sandbox Code Playgroud)
我想将表“bd - utilizadores”中的数据与“bd - áreas”连接起来。由于他们没有直接联系,我不得不使用“中间人”,即“bd - Permissões”。这是图表:
我的主要问题是,有没有其他方法可以做到这一点并获得相同的结果?
join ×10
mysql ×3
postgresql ×3
group-by ×2
sql-server ×2
aggregate ×1
optimization ×1
oracle ×1
select ×1
subquery ×1
syntax ×1
update ×1