Sql 嵌套选择查询优化
我有一个表Sql 嵌套选择查询优化,sql,Sql,我有一个表产品和一个表翻译。我对每个产品都有n翻译,但总是至少有一个默认翻译(LangID=0) 我要做的是对用户输入的字符串进行“搜索查询”。如果用户使用的语言有翻译(比如说LangID=1),我只想搜索该语言的翻译(也不想搜索默认语言),但如果没有所需语言的翻译,我想搜索默认翻译。因此,基本上默认的翻译只是一种退步 我想到的是: SELECT * FROM products p JOIN translations t ON p.ID = t.ProductID WHERE (t.LangI
产品
和一个表翻译
。我对每个产品都有n
翻译,但总是至少有一个默认翻译(LangID=0
)
我要做的是对用户输入的字符串进行“搜索查询”。如果用户使用的语言有翻译(比如说LangID=1
),我只想搜索该语言的翻译(也不想搜索默认语言),但如果没有所需语言的翻译,我想搜索默认翻译。因此,基本上默认的翻译只是一种退步
我想到的是:
SELECT * FROM products p JOIN translations t ON p.ID = t.ProductID
WHERE (t.LangID = 1 OR (t.LangID = 0 AND NOT EXISTS (SELECT id FROM translations t2 WHERE t2.ProductID = p.ID AND t2.LangID = 1))
AND t.Translation LIKE "Foo%" `
这是最好的方法还是不使用嵌套的select就可以做到这一点?或者有更好的(性能方面的)查询/方法吗?您可以这样做,但不清楚执行计划是好是坏。
或
和的组合存在
不能可靠地产生一个好的计划
只需加入两次即可更安全、更快:
select *
from products p
left join translations t1 on t1.langid = 1 and ...
left join translations t0 on t1.langid is null and t0.langid = 0 and ...
然后使用t1
的值(如果存在)。如果不是,则使用t0
的值。谓词t1.langid为null
是可选的,但是如果第一个连接成功,它允许SQL Server(希望如此)跳过第二个连接。我见过这种模式起作用,但假设它总是起作用是不安全的
这将产生一个可靠且简单的计划
with t as (
SELECT * FROM products p JOIN translations t ON p.ID = t.ProductID
WHERE t.LangID = 1 AND t.Translation LIKE "Foo%")
select * from t
union all
SELECT * FROM products p, translations t
where (select count(*) from t) = 0
and p.ID = t.ProductID
and t.LangID = 0 AND t.Translation LIKE "Foo%"';
这是一种Oracle语法,t只是一个子查询(使用可以为子查询命名)
如果计算t的过程很复杂,则此查询可能会更快
另外,您的数据库可能不会对WHERE条件使用捷径评估。需要测试(实际上Oracle不保证它的使用,但Oracle optimizer足够智能,所以它在我的情况下工作)谢谢这是对我最好的答案。我编写的完整查询:
select p.Id,COALESCE(t1.Translation,t0.Translation)从产品p左连接翻译t1到t1.ProductId=p.Id,t1.LanguageId=1左连接翻译t0到t0.ProductId=p.Id,t1.LanguageId=0,其中t1.Translation像'Foo%'或t0.Translation像'Foo%
。