Merge加入CARTESIAN总是很危险吗?
我有很多查询,成本从7到40不等,但遵循merge join cartesian执行.
当我的查询成本较低时,我是否应该真的打扰合并加入笛卡儿?
我真的需要帮助.
任何帮助是极大的赞赏.
谢谢你,Savitha
我在MySQL平台上运行以下SQL查询.
表A是具有单列(主键)和25K行的表.表B有几列和75K行.
执行以下查询需要20分钟.如果你能提供帮助我会很高兴的.
INSERT INTO sometable
SELECT A.PrimaryKeyColumn as keyword, 'SomeText', B.*
FROM A, B
WHERE B.PrimaryKeyColumn = CONCAT(A.PrimaryKeyColumn, B.NotUniqueButIndexedColumn);
Run Code Online (Sandbox Code Playgroud) 我有一个 T-SQL 查询 (SQL Server 2012) 可以完成这项工作,但是当我查看执行计划时,我看到一个排序运算符带有警告:“运算符在执行期间使用 tempdb 来溢出数据,溢出级别为 1 ”。
到目前为止我所做的阅读表明,如果我使用“order by”子句,我可以消除这个排序迭代器。这对我来说不是一个选择,因为我无法进行子查询排序,并且对最外层查询进行排序不会删除排序迭代器。
我在之前的执行计划建议我应该添加的地方添加了非聚集索引。
我还能做些什么来解决这个“tempdb 溢出”警告吗?此时我没有更多的想法。
谢谢你的任何想法。
USE MIA_2014_15_v1;
GO
/*
Notes:
* The outer query exists so that I can filter by a windowed function (Date_Count).
*/
SELECT q.Campus,
q.Student_ID,
q.Student_Name,
q.DATEIN,
q.TIMEIN,
q.[TIMEOUT],
q.Date_Count
FROM (
SELECT TC_Hours.Campus,
TC_Hours.[Student ID] AS Student_ID,
Students.Student_Name,
TC_Hours.[Date] AS DATEIN,
TC_Hours.[Time In] AS TIMEIN,
TC_Hours.[Time Out] AS TIMEOUT,
count(TC_Hours.[Date]) OVER (
PARTITION BY TC_Hours.Campus,
TC_Hours.[Student ID],
TC_Hours.[Date]
) AS Date_Count
FROM …
Run Code Online (Sandbox Code Playgroud) 我们的Oracle数据库应用程序包含一个名为PERSON
This Table的表包含一个名为的列.PERSON_NAME
此外,我们INDEX
在此列上有一个加速SELECT
使用此列的列
所以当我们使用以下SQL语句时性能很好
SELECT *
FROM PERSON
WHERE 1=1
AND PERSON_NAME = ' Yajli '
;
Run Code Online (Sandbox Code Playgroud)
但在某些商业案例中,
我们需要通过搜索来PERSON_NAME
区分大小写
所以我们尝试遵循SQL语句
SELECT *
FROM PERSON
WHERE 1=1
AND UPPER(PERSON_NAME) = UPPER(' YajLi ')
;
Run Code Online (Sandbox Code Playgroud)
但它导致我们的BAD性能和SELECT查询在这种情况下需要花费很多时间
任何帮助如何一起提高SELECT
两种情况的性能
*搜索方式PERSON_NAME
不区分大小写
*搜索PERSON_NAME
方式区分大小写
这是运行速度非常慢的查询的tkprof输出(警告:它很长:-)):
SELECT mbr_comment_idn, mbr_crt_dt, mbr_data_source, mbr_dol_bl_rmo_ind, mbr_dxcg_ctl_member, mbr_employment_start_dt, mbr_employment_term_dt, mbr_entity_active, mbr_ethnicity_idn, mbr_general_health_status_code, mbr_hand_dominant_code, mbr_hgt_feet, mbr_hgt_inches, mbr_highest_edu_level, mbr_insd_addr_idn, mbr_insd_alt_id, mbr_insd_name, mbr_insd_ssn_tin, mbr_is_smoker, mbr_is_vip, mbr_lmbr_first_name, mbr_lmbr_last_name, mbr_marital_status_cd, mbr_mbr_birth_dt, mbr_mbr_death_dt, mbr_mbr_expired, mbr_mbr_first_name, mbr_mbr_gender_cd, mbr_mbr_idn, mbr_mbr_ins_type, mbr_mbr_isreadonly, mbr_mbr_last_name, mbr_mbr_middle_name, mbr_mbr_name, mbr_mbr_status_idn, mbr_mpi_id, mbr_preferred_am_pm, mbr_preferred_time, mbr_prv_innetwork, mbr_rep_addr_idn, mbr_rep_name, mbr_rp_mbr_id, mbr_same_mbr_ins, mbr_special_needs_cd, mbr_timezone, mbr_upd_dt, mbr_user_idn, mbr_wgt, mbr_work_status_idn
FROM (SELECT /*+ FIRST_ROWS(1) */ mbr_comment_idn, mbr_crt_dt, mbr_data_source, mbr_dol_bl_rmo_ind, mbr_dxcg_ctl_member, mbr_employment_start_dt, mbr_employment_term_dt, mbr_entity_active, mbr_ethnicity_idn, mbr_general_health_status_code, mbr_hand_dominant_code, mbr_hgt_feet, mbr_hgt_inches, mbr_highest_edu_level, mbr_insd_addr_idn, mbr_insd_alt_id, mbr_insd_name, mbr_insd_ssn_tin, mbr_is_smoker, mbr_is_vip, mbr_lmbr_first_name, mbr_lmbr_last_name, …
Run Code Online (Sandbox Code Playgroud) 你们可以查看以下对Oracle DB的查询并指出错误:
SELECT t1.name FROM t1, t2 WHERE t1.id = t2.id AND t2.empno IN (1, 2, 3, …, 200)
Run Code Online (Sandbox Code Playgroud)
查询统计:
指数:
t2.empno
被编入索引.
t1.id
被编入索引.
t2.id
被编入索引.
更新
上面的查询只是我使用的查询的示例副本.下面是一个更真实的形式
解释计划
查询:
SELECT
PRODUCT_REPRESENTATION_SK
FROM
Product_Representation pr
, Design_Object do
, Files files
,EPS_STATUS epsStatus
,EPS_ERROR_CODES epsError
,VIEW_TYPE viewTable
WHERE
pr.DESIGN_OBJECT_SK = do.DESIGN_OBJECT_SK
AND pr.LAYER_NAME !='Layer 0'
AND epsStatus.EPS_STATUS_SK = pr.EPS_STATUS
AND epsError.EPS_ERROR_CODE = pr.EPS_ERROR_CODE
AND viewTable.VIEW_TYPE_ID = pr.VIEW_TYPE_ID
AND files.pim_id = do.PIM_ID
AND do.DESIGN_OBJECT_ID IN
(
147086,149924,140458,135068,145197,134774,141837,138568,141731,138772,143769,141739,149113,148809,141072,141732,143974,147076,143972,141078,141925,134643,139701,141729,147078,139120,137097,147072,138261,149700,149701,139127,147070,149702,136766,146829,135762,140155,148459,138061,138762............................................. 200 such …
Run Code Online (Sandbox Code Playgroud) 我有一个这种形式的查询,平均需要约100个子句元素,并且在极少数情况下> 1000个元素.如果大于1000个元素,我们将把in子句中的内容减少到1000(Oracle最大值).
SQL的形式是
Run Code Online (Sandbox Code Playgroud)SELECT * FROM tab WHERE PrimaryKeyID IN (1,2,3,4,5,...)
我选择的表是巨大的,将包含比我的in子句中多数百万行.我担心的是优化器可能会选择进行表扫描(我们的数据库没有最新的统计数据 - 是的 - 我知道......)
是否有一个提示我可以强制使用主键 - 不知道主键的索引名称,可能是....../*+ DO_NOT_TABLE_SCAN*/?
是否有任何创造性的方法来撤回数据
Run Code Online (Sandbox Code Playgroud)SELECT * FROM tab WHERE PrimaryKeyID = 1 UNION SELECT * FROM tab WHERE PrimaryKeyID = 2 UNION SELECT * FROM tab WHERE PrimaryKeyID = 2 UNION ....
我有两组来自外部来源的数据 - 客户的购买日期和客户的上次电子邮件点击/开放日期.它分别存储在两个表PURCHASE_INTER和ACTIVITY_INTER表中.购买数据是多个,我需要选择上次购买日期.但活动数据对每个客户都是独一无二的.数据彼此独立,并且可能不存在其他数据集.我们在下面写了一个查询,它结合了两个表,根据person_id对它们进行分组,这是来自外部来源的客户的ID并获取最新的日期,加入我们的客户表以获取客户电子邮件,然后再次加入另一个表最终存储此数据的目的是为了知道它是否是插入或更新操作.您能否建议我如何提高此查询的性能.它非常慢,耗时超过10小时.PURCHASE_INTER和ACTIVITY_INTER表中有数百万条记录.
SELECT INTER.*, C.ID AS CUSTOMER_ID, C.EMAIL AS CUSTOMER_EMAIL, LSI.ID AS INTERACTION_ID, ROW_NUMBER() OVER (ORDER BY PERSON_ID ASC) AS RN FROM (
SELECT PERSON_ID AS PERSON_ID,
MAX(LAST_CLICK_DATE) AS LAST_CLICK_DATE,
MAX(LAST_OPEN_DATE) AS LAST_OPEN_DATE,
MAX(LAST_PURCHASE_DATE) AS LAST_PURCHASE_DATE
FROM (
SELECT ACT.PERSON_ID AS PERSON_ID,
ACT.LAST_CLICK_DATE AS LAST_CLICK_DATE,
ACT.LAST_OPEN_DATE AS LAST_OPEN_DATE,
NULL AS LAST_PURCHASE_DATE
FROM ACTIVITY_INTER ACT
WHERE ACT.JOB_ID = 77318317
UNION
SELECT PUR.PERSON_ID AS PERSON_ID,
NULL AS LAST_CLICK_DATE,
NULL AS LAST_OPEN_DATE,
PUR.LAST_PURCHASE_DATE AS LAST_PURCHASE_DATE
FROM PURCHASE_INTER PUR
WHERE PUR.JOB_ID = 77318317 …
Run Code Online (Sandbox Code Playgroud) 我有数十亿的记录表,表结构如下:
ID NUMBER PRIMARY KEY,
MY_SEARCH_COLUMN NUMBER,
Run Code Online (Sandbox Code Playgroud)
MY_SEARCH_COLUMN
将具有最多15位数的数字值.
我想要的是,如果匹配任何特定记录,我将只得到匹配的值,
即:如果我输入WHERE MY_SEARCH_COLUMN = 123454321
并且表有值,123454321
则只返回此值.
但如果确切的值不匹配,我将不得不从表中获得接下来的10个值.
即:如果我输入WHERE MY_SEARCH_COLUMN = 123454321
并且列没有值,123454321
那么它应该从表中返回10个大于的值123454321
这两种情况都应该包含在单个SQL查询中,我必须记住查询的性能.我已经在MY_SEARCH_COLUMN
列上创建了索引,因此欢迎其他建议来改进性能.
我有我在 sql server 上使用的以下 sql 查询。
select distinct [Value],Label,Id from(
select distinct [Name], Code, I as Id,I + ':' + [Value] as label, [Value]
from [test].[dbo].[emp]
unpivot
(
[Value]
for I in (product, model)
) as dataTable) as t
Run Code Online (Sandbox Code Playgroud)
我想要的是,如果任何[Value]
内部的 unpivot 语句为空,它应该向嵌套的 select 语句返回 'unknown'。
我如何实现它?
更新 -
//this is wrong sql. Just want to show what is required
select distinct [Value],Label,Id from(
select distinct [Name], Code, coalesce(I as Id,'unknown'),coalesce(I,'unknown') + ':' + [Value] as label, coalesce([Value],'unknown')
from …
Run Code Online (Sandbox Code Playgroud) sql-tuning ×11
sql ×8
oracle ×7
indexing ×2
performance ×2
sql-server ×2
database ×1
mysql ×1
plsql ×1
t-sql ×1