After server move a query doesn't work anymore - sql

I need some help for a problem that's driving me crazy!
I've moved an ASP + SQL Server application from an old server to a new one.
The old one was a Windows 2000 server with MSDE, and the new one is a Windows 2008 with SQL Server 2008 Express.
Everything is ok, even a little faster, except just one damned function whose asp page gives a time out.
I've tried the query within that page in a management query windows and it never ends, while in the old server it took about 1 minute to be completed.
The query is this one:
SELECT DISTINCT
TBL1.TBL1_ID,
REPLACE(TBL1_TITOLO, CHAR(13) + CHAR(10), ’ ’),
COALESCE(TBL1_DURATA, 0), TBL1_NUMERO,
FLAG_AUDIO
FROM
SPOT AS TBL1
INNER JOIN
CROSS_SPOT AS CRS ON CRS.TBL1_ID = TBL1.TBL1_ID
INNER JOIN
DESTINATARI_SPOT AS DSP ON DSP.TBL1_ID = TBL1.TBL1_ID
WHERE
DSP.PTD_ID_PUNTO = 1044
AND DSP.DSP_FLAG_OK = 1
AND TBL1.FLAG_AUDIO_TESTO = 1
AND TBL1.FLAG_AUDIO_GRAFICO = ’A’
AND CRS.CRS_STATO > 2
OR TBL1.TBL1_ID IN (SELECT ID
FROM V_VIEW1
WHERE ID IS NOT NULL AND V_VIEW1.ID_MODULO = 403721)
OR TBL1.TBL1_ID IN (SELECT TBL1_ID
FROM V_VIEW2
WHERE V_VIEW2.ID_PUNTO = 1044)
ORDER BY
TBL1_NUMERO
I've tried to transform the 2 views in last lines into tables and the query works, even if a little slower than before.
I've migrated the db with it's backup/restore function. Could it be and index problem?
Any suggestions?
Thanks in advance!
Alessandro

Run:
--Defrag all indexes
sp_msForEachTable 'DBCC DBREINDEX (''?'')'
--Update all statistics
sp_msForEachTable 'UPDATE STATISTICS ? WITH FULLSCAN'
If that doesn't "just fix it", it's going to some subtle "improvement" in the SQL Server optimizer that made things worse.
Try the index tuning wizard (or whatever its SSMS2008 equivalent).
After that, you'll have to start picking the query apart, removing things until it runs fast. Since you have 2 OR clauses, you basically have 3 separate queries:
SELECT ... FROM ...
WHERE DSP.PTD_ID_PUNTO = 1044
AND DSP.DSP_FLAG_OK = 1
AND TBL1.FLAG_AUDIO_TESTO=1
AND TBL1.FLAG_AUDIO_GRAFICO=’A’
AND CRS.CRS_STATO>2
--UNION
SELECT ... FROM ...
WHERE TBL1.TBL1_ID IN (
SELECT ID
FROM V_VIEW1
WHERE ID IS NOT NULL
AND V_VIEW1.ID_MODULO = 403721
)
--UNION
SELECT ... FROM ...
WHERE TBL1.TBL1_ID IN (
SELECT TBL1_ID
FROM V_VIEW2
WHERE V_VIEW2.ID_PUNTO = 1044
)
See which one of those is the slowest.
p.s. A query taking a minute is pretty bad. My opinion is that queries should return instantly (within the limits of human observation)

Related

Oracle Query takes ages to execute

I have this below Oracle query. It takes ages to execute.
Select Distinct Z.WH_Source,
substr(Z.L_Y_Month,0,4) || '-' || substr(Z.L_Y_Month,5) Ld_Yr_Mth,
m.model_Name, p.SR, p.PLATE_NO, pp.value, z.CNT_number, z.platform_SR_number,
z.account_name, z.owner_name, z.operator_name, z.jetcare_expiry_date, z.wave,
z.address, z.country, substr(z.CNT_status, 10) ctstatus,
ALLOEM.GET_CNT_TYRE_SR#TNS_GG(z.CNT_number, Z.WH_Source, Z.L_Y_Month,
z.platform_SR_number, '¿')
product_SR_number
From MST.ROLE p
inner join MST.model m on m.model_id = p.model_id
left join MST.ROLEproperty pp on pp.ROLE_id = p.ROLE_id
and pp.property_lookup = 'SSG-WH-ENROLL'
left join alloem.Z_SSG_HM_LOG#TNS_GG z on z.camp_ac_ROLE_id = p.ROLE_id
Where
1 = 1 or z.L_Y_Month = 1
Order By 1, 2 desc, 3,4
If i remove this line,
ALLOEM.GET_CNT_TYRE_SR#TNS_GG(z.CNT_number, Z.WH_Source, Z.L_Y_Month,
z.platform_SR_number, '¿')
it executes very fast. But, I can't remove the line. Is there any way to make this query to execute fast.?
If i remove this line,
ALLOEM.GET_CNT_TYRE_SR#TNS_GG(z.CNT_number, Z.WH_Source,
Z.L_Y_Month, z.platform_SR_number, '¿')
it executes very fast. But, I can't remove the line. Is there any way to make this query to execute fast.?
Query tuning is a complex thing. Without table structures, indexes, execution plan or statistics it is very hard to provide one universal answer.
Anyway I would try scalar subquery caching(if applicable):
ALLOEM.GET_CNT_TYRE_SR#TNS_GG(z.CNT_number, Z.WH_Source, Z.L_Y_Month,
z.platform_SR_number, '¿')
=>
(SELECT ALLOEM.GET_CNT_TYRE_SR#TNS_GG(z.CNT_number, Z.WH_Source,Z.L_Y_Month,
z.platform_SR_number, '¿') FROM dual)
Also usage of DISTINCT may indicate some problems with normalization. If possible please fix underlying problem and remove it.
Finally you should avoid using positional ORDER BY (it is commom anti-pattern).
This:
alloem.Z_SSG_HM_LOG#TNS_GG
suggests that you fetch data over a database link. It is usually slower than fetching data locally. So, if you can afford it & if your query manipulates "static" data (i.e. nothing changes in Z_SSG_HM_LOG table frequently) and - even if it does - the amount of data isn't very high, consider creating a materialized view (MV) in schema you're connected to while running that query. You can even create index(es) on a MV so ... hopefully, everything will run faster without too much effort.

SQL Server query issues

We have a SQL Server 2012 database with our live project including multiple tables and records, Basically We are facing a problem with SQL queries on a table where two same SQL queries. The first SQL query is taking less execution time and second SQL query is getting tremendously slow to execute.
I don't know why it is happening someone could help me to solve this problem?
Our two queries are given below....
First query (taking so much time to execute):
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 112 Order By ID DESC) AS Events)
Second query (taking less execution time):
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 56 Order By ID DESC) AS Events
I see Both queries are similar with an exception of tracker id..so my best guess would be ,this query might be a victim of Parameter sniffing..
Try using Option(Recompile) like below to see if this is the cause and follow article referred in above link for resolution
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 56 Order By ID DESC
option(recompile)
AS Events)

Sybase DB - How to store a SELECT query result in a variable?

I need to store the result of the SELECT query below in a variable to cut down on computation time. The results are of the form 'X', 'Y', 'Z', ...
WHERE
PEL.kuerzel in (SELECT KL.kuerzel from ictq.KLE KL WHERE FachgruppeKuerzel=526)
Right now the SELECT query gets executed 3 times for each of ~2000 entries. If I was able to store the result locally, I would have to run it only once.
I'm working on a Sybase 11 database. How can I achieve this or anything similar?
The subquery where the snippet was taken from, out of a 150 line query alltogether:
SELECT list(PEL.kuerzel) from ictq.PEpisode PE
INNER JOIN ictq.PEpisodeLeistung PEL ON(PE.IDPATIENTEPISODE = PEL.IDPATIENTEPISODE)
WHERE
PE.IDPATIENTKLINIK = P.IDPATIENTKLINIK and
PEL.Datum between dateadd(month, -12, #startdatum) and #startdatum and
PEL.kuerzel in (SELECT kl.kuerzel from ictq.KLE kl where FachgruppeKuerzel=526)
I have no control over the structure and cannot add anything. The query in itself is legacy work and I'm happy it works as it is now. The slow computation, however, needs an overhaul.
It is often more efficient to use exists rather than in, or to move the in subquery to the from clause:
FROM PEL JOIN
(SELECT DISTINCT KL.kuerzel
FROM ictq.KLE KL
WHERE FachgruppeKuerzel = 526
) KL
ON PEL.kuerzel = KL.kuerzel;
For performance for this query, you want an index on ictq.KLE(FachgruppeKuerzel, kuerzel) and PEL(kuerzel).

SQL query works in PL/SQL but not in Visual Studio

I searched online and found out many had the same problem, but non of the solutions worked for me.
I'm really hoping you could help me:
I have this ORACLE SQL query that is working fine in PL/SQL:
select a.bzq_terminate_provider, a.callsnum, a.at_call_dur_sec, sum_charge
From (select * from usage_cycle_sum
where ban='80072922' and ben='1'
and subscriber_no='036585305'
and start_cycle_code ='20150207'
and feature_code_rank='1') a, (select bzq_terminate_provider,sum(charge_amount) as sum_charge from usage_cycle_sum
where ban='80072922' and ben='1'
and subscriber_no='036585305'
and start_cycle_code ='20150207' group by bzq_terminate_provider) b
where a.bzq_terminate_provider=b.bzq_terminate_provider
I also tried this other version that works fine as well:
select PROVIDER,sum(CALLS),sum(CHARGE),sum(DUR)
from (
select bzq_terminate_provider PROVIDER,callsnum CALLS,charge_amount CHARGE,at_call_dur_sec DUR
from usage_cycle_sum
where ban='80072922' and ben='1'
and subscriber_no='036585305'
and start_cycle_code ='20150207'
and feature_code_rank='1'
union
select bzq_terminate_provider PROVIDER,0 CALLS,charge_amount CHARGE,0 DUR
from usage_cycle_sum
where ban='80072922' and ben='1'
and subscriber_no='036585305'
and start_cycle_code ='20150207'
and feature_code_rank='2'
)
group by PROVIDER
My problem is that when i create a datagrid in Visual Studio web application, i get an error: syntax error: expecting identifier or quoted identifier
The connection is ok, i checked the simple select queries as well as the whole union part in the second query i attached, they work!
But when i use those two versions, i get this error.
What can be the problem? Is there another way to solve this?
Thanks.
EDIT 21/06/2015
It seems that visual studio doesn't work well with complex queries and i'm still looking for a solution for this, since my next queries are more complex...
Your second query is so much nicer to write as:
select bzq_terminate_provider as PROVIDER, sum(callsnum) as CALLS,
sum(charge_amount) as CHARGE, sum(at_call_dur_sec) as DUR
from usage_cycle_sum
where ban = '80072922' and ben = '1' and
subscriber_no = '036585305' and
start_cycle_code ='20150207' and
feature_code_rank in ('1', '2')
group by bzq_terminate_provider ;
Or, perhaps the select needs to be:
select bzq_terminate_provider as PROVIDER,
sum(case when feature = '1' then callsnum else 0 end) as CALLS,
sum(charge_amount) as CHARGE,
sum(case when feature = '1' then at_call_dur_sec else 0 end) as DUR
(The first version assumed that the fields were zeroed out in the second subquery because they are NULL in the data, but that might not be true.)
However, application software is not yet smart enough to identify such awkwardly written queries, so that is not the actual problem you are facing. If the query works in the database, but not in the application, then typical problems are:
The application is not connected to the right database.
The application does not have permissions on the database or table.
The application query is different from the query run in the database, typically due to some substitution problem.
The results from running the query in the application are not being interpreted correctly.

Oracle Query gets Stuck in the Same Place Even After Query is Altered

This has been bugging me for about 4 hours, so I thought it's time to seek some help. I can't find anything similar online, but mainly because the values are quite specific and I'm not really sure what to look for...
This is a problem I'm having with an Oracle script, running in SQLPlus 10.2.0.5.
The Problem:
(Names and real data has been changed to protect the identity of the suspects)
I have a table called MONKEYS and a table called MONKEY_PUZZLES, which look a bit like this:
MONKEYS
MONKEY_ID
GIRAFFE_ID
MONKEY_PUZZLE_ID
MONKEY_PUZZLES
MONKEY_PUZZLE_ID
GIRAFFE_ID
MONKEY_PUZZLES.GIRAFFE_ID and MONKEYS.GIRAFFE_ID match, but there are n MONKEYS per MONKEY_PUZZLE (so MONKEY_PUZZLES.GIRAFFE_ID 1 might match to MONKEY.MONKEY_ID 1, 2 and 334).
I want to set the MONKEYS.MONKEY_PUZZLE_ID field, based on the MONKEY_PUZZLES.MONKEY_PUZZLE_ID field, because currently my MONKEYS.MONKEY_PUZZLE_ID field is null. I have indexes on:
MONKEYS.MONKEY_ID (primary key with index)
MONKEYS.GIRAFFE_ID
MONKEY_PUZZLES.MONKEY_PUZZLE_ID (primary key with index)
MONKEY_PUZZLES.GIRAFFE_ID
I also have over 1.6 million rows in the MONKEYS table and over 50,000 rows in the MONKEY_PUZZLES table.
I was originally using the following query:
UPDATE MONKEYS M SET M.MONKEY_PUZZLE_ID =
(SELECT MP.MONKEY_PUZZLE_ID FROM MONKEY_PUZZLES MP
WHERE M.GIRAFFE_ID = MP.GIRAFFE_ID
AND MP.GIRAFFE_ID IS NOT NULL);
However, this script would take about 2 minutes to get from 0% to 92.67% complete, then it took well over 25 minutes to get to 94% complete. I eventually stopped the script. I ran it a few times (I was playing about with different indexes and DBMS_STATS), but each time it would get to 92.67% and crap out.
So I thought it must be my script. I went back to square one, ate a banana, said "Oook" a lot and came up with the following variation script, which is much more explicit:
UPDATE MONKEYS M2 SET M2.MONKEY_PUZZLE_ID =
(SELECT X.MPID FROM
(SELECT M.MONKEY_ID MID, MP.MONKEY_PUZZLE_ID MPID
FROM MONKEYS M INNER JOIN MONKEY_PUZZLES MP
ON MP.GIRAFFE_ID = M.GIRAFFE_ID) X
WHERE X.MID = M2.MONKEY_ID);
However, it was rubbish. Even with my indexes, it took well over 5 minutes just to get to 2%, so I scrapped that one.
I then came up with the following variation, which I was pretty pleased with:
UPDATE MONKEYS M SET M.MONKEY_PUZZLE_ID =
(SELECT MP.MONKEY_PUZZLE_ID
FROM MONKEY_PUZZLES MP
WHERE M.GIRAFFE_ID = MP.GIRAFFE_ID
AND EXISTS
(SELECT 1 FROM MONKEY_PUZZLES MP2
WHERE M.GIRAFFE_ID = MP2.GIRAFFE_ID));
However, and I really couldn't believe my eyes, this script behaved almost exactly like the first; running in about 2 minutes, from 0% up to 92.67% complete, then taking absolutely ages to get any further. What is it with 92.67%?!
The total number of blocks is 41,717, so it gets to about 38,000 blocks before it seems to significantly slow down.
In case you're wondering, I'm using the following query on a separate SQLPlus session to calculate the %age complete:
SELECT X.*, TO_CHAR(SYSDATE, 'HH24:MI:SS') TIMESTAMP
FROM (select sid, serial#, opname, sofar, totalwork,
round(sofar/totalwork*100,2) "% Complete" from v$session_longops) X
WHERE "% Complete" < 100 and totalwork > 0;
(which is a variation of this: http://searchoracle.techtarget.com/tip/Tracking-the-progress-of-long-running-queries)
Please help put a poor tiger out of his misery!
P.S. I'm going to leave the script running overnight and I'll update in the morning if it reaches 100%.
EDIT: It reached 100% eventually after only 57minutes (so not all that bad), but considering it reached 92.67% in 2 minutes, it's pretty terrible!
I have no explanation for the specific symptoms you're seeing -- possibly the execution plan for the update would help explain it -- but in any case I would expect this to perform better:
MERGE INTO monkeys m
USING monkey_puzzles mp
ON (mp.giraffe_id = m.giraffe_id)
WHEN MATCHED THEN UPDATE SET m.monkey_puzzle_id = mp.monkey_puzzle_id
If you're having problems with something like this then the simplest thing to do is ignore it completely. NB Doesn't solve the reason for the problem! For this query, and yours, you should really have an index on giraffe_id in monkey_puzzles; Giraffe_id, monkey_puzzle_id would be even better.
declare
i number(10) := 0;
begin
for xx in ( select rowid as rid, giraffe_id
from monkeys ) loop
UPDATE MONKEYS M
SET M.MONKEY_PUZZLE_ID = ( SELECT MP.MONKEY_PUZZLE_ID
FROM MONKEY_PUZZLES MP
WHERE MP.GIRAFFE_ID = xx.giraffe_id )
WHERE rowid = xx.rid
;
i := i + 1;
if mod(i,1000) = 0 then
commit;
-- and some show-boating from memory (if you're using PL\SQL)
dbms_application_info.set_module('Updating Monkeys', 'Total: ' || i );
end if;
end loop;
commit;
end;
/