Speed up Oracle SQL Developer query in large Oracle Database - sql

I am querying an Oracle DB using Oracle SQL Developer. The query is running slowly. I am away that using Distinct is likely slowing me down. But I haven't been able to produce unique rows without the Distinct call. The database contains no duplicate rows. So, it is likely that I malformed this query. How do I speed up this query? The query is as follows:
SELECT DISTINCT
view1.table1.col1,
view1.table2.col2,
view1.table2.col3,
view1.table1.col4,
view1.table3.col5,
view1.table4.col6
FROM
view1.table1,
view1.table3,
view1.table2,
view1.table4
WHERE
table1.col1 = table2.col7
AND
table1.col4 = table3.col8
AND
table1.col4 >= '19-DEC-20'
AND
table4.col9 = table3.col10 ```

table1: INDEX(col4, col1)
table3: INDEX(col8, col5, col10)
table2: INDEX(col7, col2, col3)
table4: INDEX(col9, col6)

Related

Oracle_How to insert data from slow select query into two tables

I have searched but can't get answer for this (maybe wrong keyword...)
I come to this problem today when I need to create a procedure to calculate data to save to 2 report table in 2 different schemas. Let say those two tables have same structure.
The query to calculate data may take more than 60 seconds (data may or may not change the result of SELECT statemant if run again)
I have two way to insert data to those two table:
Just run insert TWO time with that same select query.
Using a GTT - global temporary table to save calculated data from SELECT query, then INSERT to those two tables using data in that GTT.
I wonder if Oracle will keep cache of result for the SELECT query so that the first way will have better performance then second way (but have longer code, and duplicate code, not synchronized?).
So could anyone confirm and explain the right way to solve this for me? Or a better way of doing this?
Thank you,
Appendix 1:
INSERT INTO report_table (col1, col2, ....)
SELECT .....
FROM .....
--(long query)
;
INSERT INTO center_schema.report_table (col1, col2, ....)
SELECT .....
FROM .....
--same select query as above
;
And 2:
INSERT INTO temp_report_table(col1, col2, ...)
SELECT .....
FROM .....
--(long query)
;
INSERT INTO report_table (col1, col2, ....)
SELECT col1, col2, ....
FROM temp_report_table
;
INSERT INTO center_schema.report_table (col1, col2, ....)
SELECT col1, col2, ....
FROM temp_report_table
;
No, you have a third option - the wonderful multi-insert...
INSERT ALL
INTO report_table (col1, col2, ....)
VALUES (X.col1, X.col2, ...)
INTO center_schema.report_table (col1, col2, ...)
VALUES (X.col1, X.col2, ...)
SELECT col1, col2, ...
FROM your_table X
--(long query)
;
For a detailed info on this nice way of loading multiple tables at once please refer to the respective part of Oracle documentation.

How to merge rows in one using SQL Server 2008

I have a SQL query like this
What I want is showing one row and adding columns dynamically
Like this:
How can I do that?
you must using pivot query.
SELECT cotation_study_uid, contation_label,[OMNIPAQUE 350*50ML] AS col1, [Crane TDM] AS col2, [Annulation produit] AS col3
(SELECT *
FROM yourtable)p
PIVOT (SUM(contation_prix) FOR cotation_label IN ('OMNIPAQUE 350*50ML', 'Crane TDM', 'Annulation produit'))

How to define destination for an append query Microsoft Access

I'm trying to append two tables in MS Access at the moment. This is my SQL View of my Query at the moment:
INSERT INTO MainTable
SELECT
FROM Table1 INNER JOIN Table2 ON Table1.University = Table2.University;
Where "University" is the only field name that would have similarities between the two tables. When I try and run the query, I get this error:
Query must have at least one destination field.
I assumed that the INSERT INTO MainTable portion of my SQL was defining the destination, but apparently I am wrong. How can I specify my destination?
You must select something from your select statement.
INSERT INTO MainTable
SELECT col1, col2
FROM Table1 INNER JOIN Table2 ON Table1.University = Table2.University;
Besides Luke Ford's answer (which is correct), there's another gotcha to consider:
MS Access (at least Access 2000, where I just tested it) seems to match the columns by name.
In other words, when you execute the query from Luke's answer:
INSERT INTO MainTable
SELECT col1, col2
FROM ...
...MS Access assumes that MainTable has two columns named col1 and col2, and tries to insert col1 from your query into col1 in MainTable, and so on.
If the column names in MainTable are different, you need to specify them in the INSERT clause.
Let's say the columns in MainTable are named foo and bar, then the query needs to look like this:
INSERT INTO MainTable (foo, bar)
SELECT col1, col2
FROM ...
As other users have mentioned, your SELECT statement is empty. If you'd like to select more that just col1, col2, however, that is possible. If you want to select all columns in your two tables that are to be appended, you can use SELECT *, which will select everything in the tables.

Do SQL from non-empty table in MS Access

Suppose you have two tables in MS Access, Table1 and Table2 with the same structure (i.e. the same columns). I would like to write a query where if Table1 is empty then I have to get the data from Table2 else get the data from Table1.
I am not sure how to use IIF statements in such a way.
Just an idea. Don't have MS-Access on my machine, but SQL Server accepts it:
SELECT Col1, Col2, ... FROM (
SELECT 1 AS TAG, Col1, Col2, ... FROM Table1
UNION
SELECT 2 AS TAG, Col1, Col2, ... FROM Table2) AS TBL_PARENT
WHERE TBL_PARENT.TAG = (SELECT MIN(TAG) FROM
(SELECT TOP 1 1 AS TAG FROM Table1
UNION
SELECT TOP 1 2 AS TAG FROM Table2) AS TBL)
Explanation
If Table1 is empty, the SELECT MIN(TAG) will return 2, otherwise 1. The WHERE clause will then filter out all the rows that belong to the desired table. The outer-most SELECT is only being used becuz SQL Server doesn't allow using column alias (TAG is an alias here) in WHERE clause. Thus we have to create a temporary TBL_PARENT, so that we could access TAG column.
Since you require a somewhat conditional setting and MS Access does not run trigger or transact SQL, consider using VBA in addition to a stored or VBA SQL query.
Of course figure out which form event trigger --OnOpen, OnClick, AfterInsert, AfterUpdate-- to place this in:
IF DCount("ID", "Table1") = 0 Then
'VBA Recordset Query
db.OpenRecordset Table2sSQLString, dbOpenDynaset
'Stored SQL Query
DoCmd.OpenQuery "Table2Query"
Else
'VBA Recordset Query
db.OpenRecordset Table2SQLString, dbOpenDynaset
'Stored SQL Query
DoCmd.OpenQuery "Table1Query"
End If

How to append distinct records from one table to another

How do I append only distinct records from a master table to another table, when the master may have duplicates. Example - I only want the distinct records in the smaller table but I need to insert/append records to what I already have in the smaller table.
Ignoring any concurency issues:
insert into smaller (field, ... )
select distinct field, ... from bigger
except
select field, ... from smaller;
You can also rephrase it as a join:
insert into smaller (field, ... )
select distinct b.field, ...
from bigger b
left join smaller s on s.key = b.key
where s.key is NULL
If you don't like NOT EXISTS and EXCEPT/MINUS (cute, Remus!), you have also LEFT JOIN solution:
INSERT INTO smaller(a,b)
SELECT DISTINCT master.a, master.b FROM master
LEFT JOIN smaller ON smaller.a=master.a AND smaller.b=master.b
WHERE smaller.pkey IS NULL
You don't say the scale of the problem so I'll mention something I recently helped a friend with.
He works for an insurance company that provides supplemental Dental and Vision benefits management for other insurance companies. When they get a new client they also get a new database that can have 10's of millions of records. They wanted to identify all possible dupes with the data they already had in a master database of 100's of millions of records.
The solution we came up with was to identify two distinct combinations of field values (normalized in various ways) that would indicate a high probability of a dupe. We then created a new table containing MD5 hashes of the combos plus the id of the master record they applied to. The MD5 columns were indexed. All new records would have their combo hashes computed and if either of them had a collision with the master the new record would be kicked out to an exceptions file for some human to deal with it.
The speed of this surprised the hell out of us (in a nice way) and it has had a very acceptable false-positive rate.
You could use the distinct keyword to filter out duplicates:
insert into AnotherTable
(col1, col2, col3)
select distinct col1, col2, col3
from MasterTable
Based on Microsoft SQL Server and its Transact-SQL. Untested as always and the target_table has the same amount of rows as the source table (otherwise use columnnames between INSERT INTO and SELECT
INSERT INTO target_table
SELECT DISTINCT row1, row2
FROM source_table
WHERE NOT EXISTS(
SELECT row1, row2
FROM target_table)
Something like this would work for SQL Server (you don't mention what RDBMS you're using):
INSERT INTO table (col1, col2, col3)
SELECT DISTINCT t2.a, t2.b, t2.c
FROM table2 AS t2
WHERE NOT EXISTS (
SELECT 1
FROM table
WHERE table.col1 = t2.a AND table.col2 = t2.b AND table.col3 = t2.c
)
Tune where appropriate, depending on exactly what defines "distinctness" for your table.