How can I reduce logical reads for the following stored procedure ?
Stored Procedure
SELECT
column1,column2,...
FROM myview as v
WHERE (v.LanguageId IN (1) OR v.LanguageId IS NULL)
AND OrganisationId IN (1,2,3)
AND (v.ETypeLanguageId IN (1) OR v.ETypeLanguageId IS NULL)
AND (v.GTypeLanguageId IN (1) OR v.GTypeLanguageId IS NULL)
AND v.TargetTypeId IN (2) ORDER BY column1,column2
OPTION (RECOMPILE)
Best Regards,
Related
I have one query which cannot be modified but I need to create indexes on them to make it faster. the query is:
select allcommuni0_.assignedto as col_0_0_
from communication.vwallcommunication allcommuni0_
where (allcommuni0_.projectid in (750))
and true=any (select case when lower(communicat1_.claimnumber)=lower('193') then true else false end from communication.vwclaimdetails communicat1_
where allcommuni0_.communicationviewid=communicat1_.communicationviewid and allcommuni0_.type=communicat1_.type)
group by allcommuni0_.assignedto limit 100;
There are no indexes right now. How to create optimized index with true=any() operator on Postgres?
create an index on column type and column communicationviewid.
CREATE INDEX vwclaimdetails_lower_claimnumber_idx ON communication.claimdetails ((CASE
WHEN communicationoutboundid IS NOT NULL THEN communicationoutboundid
ELSE communicationinboundid
END),(CASE
WHEN communicationoutboundid IS NOT NULL THEN 'Outbound'::text
ELSE 'Inbound'::text
END));
Which statement is perfect or better when dealing with billion of records for comparing NULL's in merge statement. I have tried with SET ANSI_NULLS OFF but that didn't work in merge statement. Here is my two ways
ISNULL(SRCColumn,-11111) = ISNULL(DSTColumn, -11111)
Or
SRCColumn = DSTColumn OR (SRCColumn IS NULL AND DSTColumn IS NULL)
Please let me know if there is any better way to deal with it. As I have around 15 columns to compare.
SRCColumn = DSTColumn OR (SRCColumn IS NULL AND DSTColumn IS NULL)
I'd suggest that you use this version because it most accurately expresses what you want SQL Server to do.
Both statements are logically equivalent (unless -11111 is a legal value for the column), however this statement is much more recognizable, and there's probably only a negligible difference in the run-time performance of the two statements.
If you are more concerned with succinctness than performance, CHECKSUM() is also an option. It will match NULL -> NULL:
MERGE A
USING B
ON A.Key = B.Key
WHEN MATCHED AND CHECKSUM(A.Col1, A.Col2, ... ) <> CHECKSUM(B.Col1, B.Col2, ... )
THEN UPDATE SET Col1 = B.Col1, Col1 = B.Col2, ...
How about using the NOT comparison on matching:
MERGE [TGT]
USING [SRC]
ON [SRC].Key = [TGT]. Key
…
WHEN MATCHED AND
(
NOT ([TGT].[dw_patient_key] = [SRC].[dw_patient_key] OR ([TGT].[dw_patient_key] IS NULL AND [SRC].[dw_patient_key] IS NULL))
OR NOT ([TGT].[dw_patient_key] = [SRC].[dw_patient_key] OR ([TGT].[dw_patient_key] IS NULL AND [SRC].[dw_patient_key] IS NULL))
...
)
THEN UPDATE
...
I'm wondering if it's possible to parameterize the sort column in sqlite.
I'd like to prepare a single sqlite3_stmt like this (omitting checking the return codes for simplicity's sake).
sqlite3_stmt* the_statement;
const char *sql = "SELECT column1, column2, column3 FROM table1 WHERE column4 = ? ORDER BY ? ASC"
sqlite3_prepare_v2(database, sql, -1, &the_statement, NULL)
and use it like this
sqlite3_bind_int(the_statement, 1, 1);
sqlite3_bind_int(the_statement, 2, COLUMN_TO_SORT_BY);
while (sqlite3_step(the_statement) == SQLITE_ROW){
//Do something with each row.
}
sqlite3_reset()
When I execute this code changing the value of COLUMN_TO_SORT_BY from 1 to 3 my results are always returned in the same order (I think the order they are stored in the table, but it could also be as sorted by column1).
So, my question is: Can you parameterize the ORDER BY argument in a sqlite expression when using the C API?
The problem is that the value you pass in is being treated as an expression, which evaluates to a fixed value - '1' in the first case, '3' in the second. You could compose a CASE statement to order by, but it could get unwieldy quickly. Perhaps something like:
ORDER BY
CASE ?
WHEN 1 THEN column1
WHEN 2 THEN column2
WHEN 3 THEN column3
END
The CASE ... END expression isn't necessary, since the SQLite SELECT docs mention:
If the ORDER BY expression is a
constant integer K then the expression
is considered an alias for the K-th
column of the result set (columns are
numbered from left to right starting
with 1).
So simply use the following statement:
SELECT column1, column2, column3 FROM sometable ORDER BY ?
And bind the column index:
sqlite3_bind_int(stmt, 1, col_index);
It seems that in PostgreSQL, empty_field != 1 (or some other value) is FALSE. If this is true, can somebody tell me how to compare with empty fields?
I have following query, which translates to "select all posts in users group for which one hasn't voted yet:
SELECT p.id, p.body, p.author_id, p.created_at
FROM posts p
LEFT OUTER JOIN votes v ON v.post_id = p.id
WHERE p.group_id = 1
AND v.user_id != 1
and it outputs nothing, even though votes table is empty. Maybe there is something wrong with my query and not with the logic above?
Edit: it seems that changing v.user_id != 1, to v.user_id IS DISTINCT FROM 1, did the job.
From PostgreSQL docs:
For non-null inputs, IS DISTINCT FROM
is the same as the <> operator.
However, when both inputs are null it
will return false, and when just one
input is null it will return true.
If you want to return rows where v.user_id is NULL then you need to handle that specially. One way you can fix it is to write:
AND COALESCE(v.user_id, 0) != 1
Another option is:
AND (v.user_id != 1 OR v.user_id IS NULL)
Edit: spacemonkey is correct that in PostgreSQL you should use IS DISTINCT FROM here.
NULL is a unknown value so it can never equal something. Look into using the COALESCE function.
I have a large database, that I want to do some logic to update new fields.
The primary key is id for the table harvard_assignees
The LOGIC GOES LIKE THIS
Select all of the records based on id
For each record (WHILE), if (state is NOT NULL && country is NULL), update country_out = "US" ELSE update country_out=country
I see step 1 as a PostgreSQL query and step 2 as a function. Just trying to figure out the easiest way to implement natively with the exact syntax.
====
The second function is a little more interesting, requiring (I believe) DISTINCT:
Find all DISTINCT foreign_keys (a bivariate key of pat_type,patent)
Count Records that contain that value (e.g., n=3 records have fkey "D","388585")
Update those 3 records to identify percent as 1/n (e.g., UPDATE 3 records, set percent = 1/3)
For the first one:
UPDATE
harvard_assignees
SET
country_out = (CASE
WHEN (state is NOT NULL AND country is NULL) THEN 'US'
ELSE country
END);
At first it had condition "id = ..." but I removed that because I believe you actually want to update all records.
And for the second one:
UPDATE
example_table
SET
percent = (SELECT 1/cnt FROM (SELECT count(*) AS cnt FROM example_table AS x WHERE x.fn_key_1 = example_table.fn_key_1 AND x.fn_key_2 = example_table.fn_key_2) AS tmp WHERE cnt > 0)
That one will be kind of slow though.
I'm thinking on a solution based on window functions, you may want to explore those too.