How to optimize oracle query from partitioned table? - performance

I have a partitioned table by date (by days) and a local index on the fields (including date field). If I make a query:
SELECT * FROM table t WHERE t.fdate = '30.06.2011'
it is fulfilled quickly, but when I make
SELECT * FROM table t WHERE EXTRACT(month from t.fdate) = 6 AND
EXTRACT(year from t.fdate) = 2011
it is fulfilled approximately 200 seconds.
How to optimize this query? May be I need to create local index on EXTRACT(month from date) AND EXTRACT(year from date)?

As you have an index on the date field, you should write your query in a way that this index can be used. This is not possible with the EXTRACT functions since Oracle must go through all data and compute the condition for each row to determine if it matches.
The date index can be used if you have a specific date or a range of dates. In your case, you're looking for a range of dates. So the query could be written as:
SELECT * FROM TABLE T
WHERE T.FDATE BETWEEN TO_DATE('1.6.2011', 'DD.MM.YYYY') AND TO_DATE('30.6.2011', 'DD.MM.YYYY');

Related

Select max query returning all the rows in a table in Apache Hive

I am querying my data using this query
SELECT date_col,max(rate) FROM crypto group by date_col ;
I am expecting a single row but it is returning all the rows in the table. What is the mistake in this query?
You'll get one row per date_col because you're grouping by it. If you just want the maximum rate then just do SELECT max(rate) FROM crypto;.
If you want to get the date_col for that record too then:
SELECT
date_col,
rate
FROM crypto
WHERE rate = (SELECT MAX(rate) FROM crypto)

Is expression based partitioning supported in hive?

I have a table with a column, can i create a partition based on an expression using that column
I read that IBM's Big SQL technology has this feature.
I also know we can partition in hive by a column but what about an expression?
In this case i am doing a cast..it could be any expression
CREATE TABLE INVENTORY_A (
trans_id int,
product varchar(50),
trans_ts timestamp
)
PARTITIONED BY (
cast(trans_ts as date) AS date_part
)
I expect the records to be partitioned by the date value. So I expect that when a user writes a query like
select * from INVENTORY_A where trans_ts BETWEEN timestamp '2016-06-23 14:00:00.000' AND timestamp '2016-06-23 14:59:59.000'
the query will be smart enough to break the timestamp down by the date and do a filter only on the date
You can use Dynamic partitioning and cast your variables in select query.

How to group by one column with single aggregate function but select multiple columns on oracle?

I want to group by one column with aggregate function on single column while selecting multiple other column.This is easily achieved in MySQL by query below.
SELECT sum(count),store,date,product FROM sales_log_bak where date > "2017-03-01" and date < "2017-04-05" group by date
However,above query doesn't work on oracle Database.What will be equivalent query in oracle to achieve result as given by MySQL on above query?
You can use Analytic Functions:
SELECT sum(sales_count) OVER (PARTITION BY sales_date),
store, sales_date, product
FROM sales_log_bak
where sales_date > DATE '2017-03-01' and sales_date < DATE '2017-04-05';
Note, date and count are reserved words in Oracle, you should not use them for column names.

How can I convert a date to another format at run time in Oracle?

I have a date string coming from user input in the format of DD/MM/YYYY and I need to match it against a date column in our database in the format of DD-MON-YY.
Example input is 01/01/2015 and example date column in our database:
SELECT MAX(creation_date) FROM orders;
MAX(creation_date)
------------------
06-AUG-15
I need to query in the format:
SELECT * FROM orders WHERE creation_date = 01/01/2015
and somehow have that converted to 01-JAN-15.
Is it possible with some built-in Oracle function?
Use to_date, if the column in the table is in date format
http://www.techonthenet.com/oracle/functions/to_date.php
to_char allows you to specify different formats in a SQL statement.
Example: to_char(sysdate,'DD-MON-YYYY') will display 06-AUG-2015 for today's date.
TO_CHAR
Use to_date to compare your date column to a date string, but be careful in doing so since your date column may include a time component that isn't showing when selecting from your table.
If there is no index on your date column, you can truncate it during the comparison:
SELECT * FROM orders WHERE TRUNC(creation_date) = TO_DATE('01/01/2015','mm/dd/yyyy');
If there is an index on your date column and you still want to use it then use a ranged comparison:
SELECT * FROM orders
WHERE creation_date >= TO_DATE('01/01/2015','mm/dd/yyyy')
and creation_date < TO_DATE('01/01/2015','mm/dd/yyyy')+1;

select data based on a date column

I was trying to select some data from my table using the following query:
select * from table1 where column1 = to_date('14-05-14','yy-mm-dd');
Where the column data type is DATE. I observed that, the above query won't return anything unless we modified it as,
select * from table1 where trunc(column1) = to_date('14-05-14','yy-mm-dd');
even though there are records available.
I checked the documentation for TRUNC.Can anyone please explain why this happens?
UPDATE
As per the valuable comments I think some time values may also associated with the DATE. But I cannot view/edit that time. How can I ensure there are time values associated.
Both TO_DATE and TRUNC are different. See the below example.
SQL> ALTER SESSION SET nls_date_format = 'dd/mm/yyyy hh24:mi:ss';
Session altered.
SQL> SELECT TO_DATE(SYSDATE) FROM DUAL;
TO_DATE(SYSDATE)
-------------------
28/05/2014 16:03:25
SQL> SELECT TRUNC(SYSDATE) FROM DUAL;
TRUNC(SYSDATE)
-------------------
28/05/2014 00:00:00
In Your first query to_date('14-05-14','yy-mm-dd') is comparing with the date field column1 in your table which has time values also. Whereas in Your 2nd query You are truncating the time part from table data and from Your query, that's why it's matching.
The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight).
TRUNC function will truncate the date to the day value, so that any hours, minutes, or seconds will be truncated off.
For more info please look at these below links
http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT413
http://www.techonthenet.com/oracle/functions/trunc_date.php

Resources