Does synonym uses the indexes of source table in SQL Server? - sql

I have two databases D1 and D2. I have created a synonym T1 in D2 which refer to a table T1 from the D1 database.
Now if I query using the T1 synonym in the D2 table, will it use the index of the T1 table from the D1 database?
Currently, I am in a situation where my tempdb is growing, and I found that it is because of the query on the synonym, I can't view the query plan from the D2 database as SHOWPLAN permission is denied in the D1 database, however, if I run the same query on the D1 database, it goes well, and use a proper index.
Or is there a way to create a synonym with indexes?

There should be no difference in index usage between using the synonym versus the table directly. However, the database context can make a difference in the execution plan and affect performance as well as tempdb usage of the same query.
Review the database compatibility level and database-scoped configuration settings for differences between the two databases.
Also consider the plans could be different due to other factors, such as parameter sniffing.

Related

How to tune Oracle SQL query

I want to ask whether it better to use Synonym or the actual name of the table to tune the performance of a SQL query?
A synonym is a label to an actual database object. They are used as a layer of abstraction. The main use is for referencing objects in other schemas or remote databases. Using a synonym means we don't have to change out code when we move in different environments.
The performance hit of using a synonym is the look up. Given an object name in a query the optimizer will look for matching objects in this order:
a table or view in the referenced schema (default is current schema)
a private synonym in the referenced schema
a public synonym
So, if our current schema has a table T23 the database will use that in our query rather than the table referenced by public synonym T23.
Depending on the state of the data dictionary the cost of this look up should range from utterly completely negligible to more-or-less negligible.
Using a synonym will not affect the performance of the actual query. That is, these two queries will have the same execution profile:
select * from synonym_of_some_table;
select * from other_user.some_table#remote_db;
"even it the data in the table is very large" ?
Yes, even if the data in the table is very large. Using a synonym won't affect retrieving the data either way. Synonyms are not like views, which can make tuning a lot harder.

SQL Azure - cross-database queries

We have two databases let say 'D1' and 'D2'. There is one table in each database, say T1 in D1 and T2 in D2.
Now I want to write a store procedure in database D1 which will access table in database D2 something like below code...
USE D1
GO
Create or replace sp_test
(
--other detials
SELECT * FROM D2.dbo.T2
)
GO
Any idea how can I do this?
Note: Earlier we used to have both the databases on to same server. So I didn't face any problem. But now after migrating to Azure I don't have any idea how we can do this. Also as per my information we don't have linked server feature available in SQL-Azure.
Azure SQL Database (or SQL Azure) don't support cross-database queries, so there's no work around other than getting rid of those cross-database queries...
If you are in SQL Azure V12 and your server has a few databases with same edition and you are not permanently depend on cross database transactions(I meant just for a few things, please note that not for cross database queries, this you still need to do at application level), you may want to use sp_bindsession. If you are lucky enough you may end up both databases on the same server. The recommendation is not for any application development but one time things.
This is now possible in SQL Azure. Essentially you need to create an external data source in D1 and an eternal table in D1 that matches the target table in D2.
Something like this
USE D1
-- Not sure if the following line is necessary. Omit it and if SQL Squeals, put it in.
CREATE MASTER KEY ENCRYPTION BY PASSWORD='MasterKeyPassword';
CREATE DATABASE SCOPED CREDENTIAL D2User WITH IDENTITY='D2UserID', SECRET='D2UserPassword';
CREATE EXTERNAL DATA SOURCE D2DataSource
WITH
(
TYPE=RDBMS,
LOCATION='d2.database.windows.net',
DATABASE_NAME='D2',
CREDENTIAL=D2User
);
CREATE EXTERNAL TABLE [dbo].[T2](
[ID] [INT] NOT NULL,
[Info] [NVARCHAR] (25) NULL
)
WITH
(
DATA_SOURCE = D2DataSource
);
Of course you have to replace all the relevant details with your own chosen passwords, database locations etc.

DISTRIBUTE BY notices in Greenplum

Say I run the following query on psql:
> select a.c1, b.c2 into temp_table from db.A as a inner join db.B as b
> on a.x = b.x limit 10;
I get the following message:
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using
column(s) named 'c1' as the Greenplum Database data distribution key
for this table.
HINT: The 'DISTRIBUTED BY' clause determines the
distribution of data. Make sure column(s) chosen are the optimal
data distribution key to minimize skew.
What is a DISTRIBUTED BY column?
Where is temp_table stored? Is it stored on my client or on the server?
DISTRIBUTED BY is how Greenplum determines which segment will store each row. Because Greenplum is an MPP database in most production databases you will have multiple segment servers. You want to make sure that the Distribution column is the column you will join on usaly.
temp_table is a table that will be created for you on the Greenplum cluster. If you haven't set search_path to something else it will be in the public schema.
For your first question, the DISTRIBUTE BY clause is used for telling the database server how to store the database on the disk. (Create Table Documentation)
I did see one thing right away that could be wrong with the syntax on your Join clause where you say on a.x = s.x --> there is no table referenced as s. Maybe your problem is as simple as changing this to on a.x = b.x?
As far as where the temp table is stored, I believe it is generally stored on the database server. This would be a question for your DBA as it is a setup item when installing the database. You can always dump your data to a file on your computer and reload at a later time if you want to save your results (without printing.)
As I know, tmp table is stored in memory. It is faster when there are less data and it is recommended to use temp table. In the opposite, as temp table is stored into memory, if there are too much data it will consume very large memory. It is recommended to use regular tables with distributed clause. As it will be distributed across your cluster.
In addition, tmp table is stored into a special schema, so you don't need to specify the schema name when creating the temp table, and it only exist in the current connection, after you close the current connection, postgresql will drop the table automatically.

Will SQL Server 2005 Database Engine Tuning Advisor "tune" Temporary Tables?

I'm attempting to use Database Engine Tuning Advisor to tune my database. From the comments it's logging (it's just 40% into the analysis, after running all weekend) it appears that DTA is not capable of tuning operations on Temporary tables. Is that in fact the case?
No. Because in order to apply an index to a transient temporary table you would have to add the index to the script that used the temporary table. It can't just be applied to a non-permanent table as a set-and-forget operation.
What you can do is create a real table with the same name in your database and remove the creation of the temp table from scripts and replace with TRUNCATE TABLE. If you create this table, and then perform actions against it, the DTA will recommend indexing for the permanent table. You then script these recommended indexes, and add them to the temp table in your script.
Also: be aware that while the DTA does a pretty good job in most cases, it doesn't always get it right...

SQL Server Table Synonyms with Indexes

I have multiple databases on a single instance of SQL Server 2005. I've created a synonym on one database to access a table on another database and when writing my queries, I'd like to utilize a specific index, however, when evaluating the execution plan, it doesn't appear to use it. If I write the query to access the database explicitly, it works, but I can't seem to get it to work using a synonym. For example:
select *
from testdb..testtable with (index(testindex))
|--Nested Loops(Inner Join, OUTER REFERENCES:([testdb].[dbo].[testtable].[id]))
|--Index Scan(OBJECT:([testdb].[dbo].[testtable].[testindex]))
|--Clustered Index Seek(OBJECT:([testdb].[dbo].[testtable].[PK_testtable]), SEEK:([testdb].[dbo].[testtable].[id]=[testdb].[dbo].[testtable].[id]) LOOKUP ORDERED FORWARD)
does not yield the same execution plan as
select *
from testdb_synonym with (index(testindex))
|--Clustered Index Scan(OBJECT:([testdb].[dbo].[testtable].[PK_testtable]))
Is this a limitation with Synonyms or is there something specific I need to do to get this to work?
This is a bug that Microsoft have fixed: see MS KB 963684
In Microsoft SQL Server 2005, you
create a synonym for a table. You run
a query against the synonym. The query
uses the INDEX optimizer hint to force
an index. If you examine the execution
plan that is generated for the query,
you may find the execution plan does
not use the forced index.
I tested the same thing and it seems that the query optimizer ignores that hint when done via a synonym. The details are I did a select * against an arbitrary table with an index hint to use a non-clustered index. Without the synonym, it does a bookmark lookup/nested loop join. With it, it does a table scan. Since there are no options on the create synonym syntax, I can only assume that the index hint is ignored. No details in BOL as to why. I would chalk it up as a "feature".
WITH INDEX hints seems to be ignored for synonyms.
CREATE SYNONYM syn_master FOR master
SELECT *
FROM syn_master WITH (INDEX (wow_i_can_write_everything_here))
compiles and runs allright despite the fact I don't have an index named wow_i_can_write_everything_here in my schema.
Do you need the hint in your case? MS recommendations is to avoid index hints if it is possible due to the fact that may invalidate a more optimized plan. Even if it is optimized today it may be inefficiens tomorrow due to data load etc.
I tried to use a synonym without the hint in SQL server 2008 and got the same execution plan with the synonym as with the fully qualified name (database.schema.table).
I even tried to use the synonym with an index hint and successfully forced a non clustered index seek (and a key lookup to get the rest of the data), and i get the same execution plan with fully qualified name.
Are your statisitics updated? Do you have a selective index or does SQL server think it is more efficient to use a table scan.