Oracle SQL View with select statement in where - sql

Hello I have a problem with one of my views.
I use this statement a view times
where date=(select d from user_date_table)
This works fine for the result but the perfomance is very slow.
When I do the following:
where date=to_date(
This is a lot faster but this will not work here since I have to give the view this value.
Is there anything else I can do?
Right now I've tested it with a package that has a function package_name.get_user_date that gives me the value. But this is also very slow.
Are there any other things that would maybe could make this query faster?
Thank you!

There are 2 possible ways you could try and resolve this.
Does user_date_table have duplicate dates in it?
If not, then you could join to this table in the query instead of putting it into a where clause.
If it does, then you could change the query in the view to
select ...
from yourTable t
where exists
(
select *
from user_date_table udt
where udt.d = r.date
)
Also, check and see what indexes are on the user_date_table. Maybe there is a function based index on to_date(d) which is why this works faster.

Related

is there an alternative to query with DELETE snowflake SQL statement with CTE?

On snowflake, is there an alternative to query with DELETE SQL statement with CTE? seems it is not possible.
with t as (
select * from "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."CALL_CENTER"
), p as (select t.CC_REC_END_DATE, t.CC_CALL_CENTER_ID , t.CC_REC_START_DATE from t where 1=1 AND t.CC_REC_START_DATE > '2000-01-01')
delete from p
For example: if we use a select, we got some results.
but if I use a delete. It shows a syntax error
The problem with this thinking is that SELECT returns some values, that might, or might not be, matching individual records in your table. In principle, they might return even combinations of values from multiple tables, multiple rows, or no rows at all even. What would you want DELETE to do then?
So, for DELETE, you need to specify which rows in the table you're operating on are deleted. You can do it with a simple WHERE clause, or with a USING clause.
If you want CTEs with DELETE, the closest would be to use USING, put a subquery there, and join its result with the table. In many cases that's a very useful approach, but it is causing a join, which has a performance impact. Example:
delete from CALL_CENTER t
using (
select cc_call_center_sk from CALL_CENTER
where 1=1 AND t.CC_REC_START_DATE > '2000-01-01'
) AS sub
where sub.cc_call_center_sk = t.cc_call_center_sk.
But again, for your query it doesn't make much sense, and what #cddt wrote is probably your best bet.
The expected outcome from the question is not clear, so this is my best interpretation of it.
It seems like you want to delete records from the table SNOWFLAKE_SAMPLE_DATA.TPCDS_SF100TCL.CALL_CENTER where the field CC_REC_START_DATE is greater than 2000-01-01. If that's what you want to achieve, then you don't need a CTE at all.
DELETE FROM SNOWFLAKE_SAMPLE_DATA.TPCDS_SF100TCL.CALL_CENTER t
WHERE t.CC_REC_START_DATE > '2000-01-01'

Performance/Optimized way to perform PostgreSQL query. WHERE OR vs WHERE IN?

I have a simple query that selects all records in a table that match the id criteria provided.
SELECT * FROM table WHERE id = x or id = y or id = z;
It works fine, however I have over 50 ID's that need to be included in the where clause. So when it comes to performance, would it be better to do a WHERE IN clause, rather than OR? Or is there a better way to execute this that I am totally overlooking?
Thank you
PostrgeSQL behavior can be checked with EXPLAIN (analyze, buffers).
This is the only way to understand what database is doing.
In case your list grows big, you can try joining with a VALUES construct instead.
Please, check these:
https://dba.stackexchange.com/questions/91247/optimizing-a-postgres-query-with-a-large-in
https://www.datadoghq.com/blog/100x-faster-postgres-performance-by-changing-1-line/

How can I make large IN clauses more efficient in SQL Server?

My current query runs very slow when accessing a DB with pretty large tables
SELECT *
FROM table1
WHERE timestamp BETWEEN 635433140000000000 AND 635433150000000000
AND ID IN ('element1', 'element2', 'element3', ... , 'element 3002');
As you can see the IN clause has several thousand values. This query is executed roughly every second.
Is there another way to write it to improve performance?
Add the elements of the IN to an indexed temporary (if the elements change) or permanent table (if the elements are static) and inner join on them.
This is your query:
SELECT *
FROM table1
WHERE timestamp BETWEEN 635433140000000000 AND 635433150000000000 AND
ID IN ('element1', 'element2', 'element3', ... , 'element 3002');
The query is fine. Add an index on table1(id, timestamp).
The best answer depends on how those element ID listings are selected, but it all comes down to one thing: getting them into a table somewhere that you can join against. That will help performance tremendously. But again, the real question here is how best to get those items into a table, and that will depend on information not yet included in the question.
You should check your execution plan, I guess you could have a parameter sniffing problem caused by your between. Check if the actual rows are way off you expected values. And you can rewrite your IN to a EXISTS, which works inside like a INNER JOIN.

PostgreSQL query is slow when using NOT IN

I have a PostgreSQL function that returns a query result to pgadmin results grid REALLY FAST.
Internally, this is a simple function that uses a dblink to connect to another database and does a query return so that I can simply run
SELECT * FROM get_customer_trans();
And it runs just like a basic table query.
The issue is when I use the NOT IN clause. So I want to run the following query, but it takes forever:
SELECT * FROM get_customer_trans()
WHERE user_email NOT IN
(SELECT do_not_email_address FROM do_not_email_tbl);
How can I speed this up? Anything faster than a NOT IN clause for this scenario?
get_customer_trans() is not a table - probably some stored procedure, so query is not really trivial. You'd need to look at what this stored procedure really does to understand why it might work slow.
However, regardless of stored procedure behavior, adding following index should help a lot:
CREATE INDEX do_not_email_tbl_idx1
ON do_not_email_tbl(do_not_email_address);
This index lets NOT IN query to quickly return answer. However, NOT IN is known to have issues in older PostgreSQL versions - so make sure that you are running at least PostgreSQL 9.1 or later.
UPDATE. Try to change your query to:
SELECT t.*
FROM get_customer_trans() AS t
WHERE NOT EXISTS (
SELECT 1
FROM do_not_email_tbl
WHERE do_not_email_address = t.user_email
LIMIT 1
)
This query does not use NOT IN, and should work fast.
I think that in PostgreSQL 9.2 this query should work as fast as one with NOT IN though.
Just do it this way:
SELECT * FROM get_customer_trans() as t1 left join do_not_email_tbl as t2
on user_email = do_not_email_address
where t2.do_not_email_address is null

SQL Where Clause Against View

I have a view (actually, it's a table valued function, but the observed behavior is the same in both) that inner joins and left outer joins several other tables. When I query this view with a where clause similar to
SELECT *
FROM [v_MyView]
WHERE [Name] like '%Doe, John%'
... the query is very slow, but if I do the following...
SELECT *
FROM [v_MyView]
WHERE [ID] in
(
SELECT [ID]
FROM [v_MyView]
WHERE [Name] like '%Doe, John%'
)
it is MUCH faster. The first query is taking at least 2 minutes to return, if not longer where the second query will return in less than 5 seconds.
Any suggestions on how I can improve this? If I run the whole command as one SQL statement (without the use of a view) it is very fast as well. I believe this result is because of how a view should behave as a table in that if a view has OUTER JOINS, GROUP BYS or TOP ##, if the where clause was interpreted prior to vs after the execution of the view, the results could differ. My question is why wouldn't SQL optimize my first query to something as efficient as my second query?
EDIT
So, I was working on coming up with an example and was going to use the generally available AdventureWorks database as a backbone. While replicating my situation (which is really debugging a slow process that someone else developed, aren't they all?) I was unable to get the same results. Looking further into the query I am debugging, I realized the issue might be related to the extensive use of User Defined Scalar Valued Functions. There is heavy use of a "GetDisplayName" function that depending upon the values you pass in, it will format lastname, firstname or firstname lastname etc. If I simply omit that function and do the string formatting in the main query/TVF/view or whatever, performance is great. When looking at the execution plan, it didn't give me a clue to look at this as the issue which is why I initially ignored it.
The scalar UDFs are very likely the issue. As soon as they go into your query you've got a RBAR execution plan. It's tolerable if they're in the SELECT but if they're being used in a WHERE or JOIN clause....
A pity because they can be very useful but they're performance killers in big SELECTs and I'd suggest trying to rewrite either the UDFs to table valued or the query to avoid the UDFs, if at all possible.
Though I'm not SQL guru but most probably it is due to fact that in second query you are selecting only one column that makes it faster and secondly ID column seems to be some key and thus indexed. This can be the reason why it is faster the second way.
First Query:
SELECT * FROM [v_MyView] WHERE [Name] like '%Doe, John%'
Second query:
SELECT * FROM [v_MyView] WHERE [ID] in
(SELECT [ID] FROM [v_MyView] WHERE [Name] like '%Doe, John%')