SQL Azure and Indexed Views - sql-server

We have some Premium Azure SQL Databases, and we are attempting to use indexed views to materialize a subset of some larger tables, so the data can be used in some search / reportring queries. What I am noticing is that the query optimizer refuses to use the view.
My first attempt was to create the view and not modify the query. I thought the optimizer would substitute the view when it determined it was a better choice, but it didn't.
My second attempt I selected from the view directly, the execution plan didn't change at all.
Finally I added the (NOEXPAND) hint on the view and this time the plan did use the indexed view.
I've seen this behavior with 3 different indexed views in 3 different queries. In all 3 cases the queries performed at several orders of magnitude better. In my most recent example the duration of the query went from 90 seconds to 1 second.
I'm not a big fan of using hints to override the query optimizer, has anyone else experienced this?

Indexes views are fully supported on Azure SQL Database Premium. No functionality of indexed views is blocked or not supported on Azure SQL Database.
To be able to help you, you will have to share the database schema and a step-by-step procedure of how your reproduce the issue. I guess you won't agree to share the schema on this site, so maybe the best you can do is create a support ticket at Azure Support. Please send an email to this (azcommunity#microsoft.com) address explaining the issue, they will return instructions to have this handled by Azure Support. They will safely take a look at your schema.

Related

SQL Server move data between databases

We have a requirement where we will have to move data between different database instance on regular basis. (For e.g. some customers willing to pay more for the better performance). So this is not going to be one off.
The database tables has referential integrity. Is there a way in which this can be done without rewriting sql script (or some other method) every time we migrate customers data?
I came across this How to move data between multiple database's table while maintaining foreign-key relationships/referential integrity?. However it appears that we have write script every time we migrate data (please correct me if I misunderstood the answer on this thread).
Thanks
Edit:
Both servers are using SQL Server 2012 (same version). Its an Azure SQL Server database.
They are not necessarily linked (no firewall between them)
We are only transferring some data, not the whole database. This is only for certain customers who opted pay more.
The schema are exactly same in both databases.
Preyash - please see the documentation on the Split-Merge tool. The Split-Merge tool enables you do move data between databases, as you have described, based on a sharding key (e.g., customer ID). One modification that you will need for your application is to add a shard map (i.e., a database that understand the global state of which customers resides in which databases).
Have a look into Azure Data Sync. It is much more aligned with your requirements. But you may end up in having another SQL Azure DB to maintain a Hub. Azure data Sync follows hub-spoke pattern and will let you do all flexible directional syncs with a few minutes of syncing gap. It is more simple and can set it up very fast without any scripts and all as you wanted.

Querying Azure Search from IIS or SQL Server?

It seems easy to apply an Azure Search index to an SQL Azure database. I undertand that you query the search index using REST APIs and that the index then needs to be maintained/updated. Now, consider a web server running IIS, with an underlying SQL Server database.
What is considered best practice; querying and updating the index from the web server or from SQL Server, e.g. from within a CLR stored procedure? Are there specific design considerations here?
I work on Azure Search team and will try to help.
Querying and updating the index are two different use cases. Presumably, you want to query the index in response to user input in your Web app. (It is also possible that you have a SQL stored procedure with some complex logic that needs full test search, but that seems less likely).
Updating the index can be done in multiple ways. If you can tolerate updating your index at most every 5 minutes, use Azure Search SQL indexer automagically update the index for you - see http://azure.microsoft.com/en-us/documentation/articles/search-howto-connecting-azure-sql-database-to-azure-search-using-indexers-2015-02-28/ for details on how to do it. That article describes creating indexers using REST API, but we now have support for that in .NET SDK as well.
OTOH, if you need hard real-time updates, you can update the search index at the same time you produce data to insert / update your SQL database.
Let me know if you have any follow up questions!
HTH,
Eugene

MSSQL - Create an alias name for a database

I am using MSSQL 2014 and I am having troubles fulfilling one request from DB admin regarding the security.
Our solution contains several databases (on the same server) with stored procedures in them that have joins between the tables of two or more databases. We have one user that has same rights on all databases.
Very simplified example: one database contains Articles while the other one contains Prices, queries need to get Articles with their Prices. Queries have INNER JOIN-s between tables in those two databases.
After deployment of the solution on our client's test environment, I talked to client's DB admin and he asked me to modify the databases and users to match some of their standards. Those standards include different database names on different environments as well as one separate user per database.
If I did changed database names and users in my current solution, stored procedures would return errors due to invalid database names or invalid credentials. I asked that admin how they solved such problem in their environment and his answer was that they create database links. After googling for the solution, I found out that Oracle has CREATE DATABASE LINK option, but there is nothing similar in MSSQL (except maybe linked servers feature, but that does not solve my problem).
What I am looking for is something similar to Oracle's CREATE DATABASE LINK in MSSQL 2014, some solution that would allow execution of stored procedures without need to change the queries, but rather to create 'alias' of the databases that need to be renamed.
Does anyone have an idea how I could do this?
I just searched msdn
CREATE SYNONYM (Transact-SQL)
I know link only answers are frowned upon but that is the answer and msdn is not going away
not sure if this can be an answer but it is too long to fit a comment...
there is no tech detail in your question so i'm making a huge wild guess but maybe the problem could be avoided using many schema instead of many databases.
that way all your objects would belong to the same database and there will be no need to make cross-database calls.
obviously this solution may not fit your situation, be not applicable because of [your long list of reason here] and would also require changes whose impact cannot be estimated reading a post on SO... ^^
as a side note the customer is not always right; if they have a policy that relies upon a specific oracle feature they cannot expect to enforce that very same policy on a different rdbms that lack the feature.
actually they may expect to do so but is your job to 'educate' them (or at least try to!).
anyway if the policy is mandatory then they will be happy to pay for the extra effort required to comply, isn't it?
Starting with the obvious I think you should explain the client that although there is more than one physical database it is in fact the very same database split apart and used by the very same product. Make it clear that this shouldn't be considered like a breach in their standard.
If you can not convince them then you have to deal with two problems : different user/login and different database name.
Different user/login : You can solve this with a linked server. Linked servers aren't only for different servers or different instances, you can create a "local" linked server that will use a different login.
EXEC sp_addlinkedserver
#server='yourAlias',
#srvproduct='SQL_SERVER',
#provider='yourServer\yourInstance',
#dataSrc = 'yourDatabaseXYZ'
GO
You can easily modify the credentials used by the linked server you've just created :
In SQL Server Management Studio, open Object Explorer, expand Server Objects and ight-click the new linked servers you just created;
On the Security page specify the login you want to use.
Different database name : The only solution I can came up with is to create a SYNONYM for every object in the database. This is something others people seems to have done before and although it is not something funny it seems very doable. You can have a look here for a complete solution.
Of course you can use a SYNONYM on a linked server resource. Something like :
CREATE SYNONYM yourTable FOR [yourAlias].yourDatabaseXYZ.schemaABC.yourTable
And then you will be able to do :
-- Transparent usage of a table from another database with different credentials
SELECT * FROM yourTable;
By the way, there is a feature request to Microsoft to Allow CREATE SYNONYM for database. Maybe you'd like to upvote it
Final note :
To avoid problem like this, and like Blam also mentionned, you should consider not hardcoding the database name in your application.

SQL Server: Best way to deny sql user access to old data

Using SQL Server, what is a simple but effective means of denying access to data older than a certain date, for some users?
We can do this at the application level (a web application) but this leaves us vulnerable to scenarios such as IIS being hacked or bugs in our application. Ideally only certain SQL users should have access to certain data older than a couple of months. What is a good way of achieving this with minimal fuss?
If it makes a difference, our application uses NHibernate.
The pure SQL solution would be to create a view something like:-
CREATE USERVIEW AS (SELECT * FROM REALTABLE WHERE CREATE_DATE > CURRENT_DATE() - 30 DAYS )
Not sure how well this plays with Hibernate and of course the "CURRENT_DATE() - 30 DAYS " would only be valid in DB2 you would need a differnet function and syntax for each DBMS.
SQL Server does not offer row level security. Meaning you cannot grant SELECT to certain rows (newer than a date) while denying to other. All GRANT/DENY/REVOKE work at the whole table level.
There are some proposed workarounds like using views,see Granting Row-Level Permissions in SQL Server, but they're cumbersome and difficult to use (specially if the data is also to be updated).
Your best bet is to move the data into different tables, if possible.
Can you archive older data to tables that have more restricted access rights?
The proper way to achieve that is to archive the old data by using the SQL Server business intelligence mechanisms, but it is not an immediate task and requires some planning (and these mechanisms are not available in the low-end versions of SQL Server).

What's the best way to work with SQL Server data non-programmatically?

We have a SQL server database. To manipulate the data non-programmatically, I can use SQL Server Management Studio by right-clicking a table and selecting "Open Table". However this is slow for very large tables and sorting and filtering is cumbersome.
Typically what we have done until now is to create an Access database containing linked tables which point to the SQL Server tables and views. Opening a large table is much faster this way, and Access has easy-to-use right-click filtering and sorting.
However, since Access 2007, sorting in particular has been quite slow when working with large tables. The Access database can also inadvertently lock the database tables, blocking other processes that may need to access the data. Creating the Access database in the first place, and updating it when new tables are added to SQL Server, is also tedious.
Is there a better way to work with the data that offers the usability of Access without its drawbacks?
Joel Coehoorn's answer is of course correct, that if the data is critical or there are naive users using the data, then a application front end should be developed. That being said, I have cases where a wise user (ok, me) user needs to just get in there and poke around.
Instead of directly looking at the tables, use MS Access but use queries to narrow down what you're looking at both column wise and row wise. That will improve the speed. Then edit the query properties and make sure that the query is No Locks. That should eliminate any blocking behavior. You may want to limit the number of rows returned which again will improve the speed. You can still edit the data in the query as you look at it.
Depending on what you're looking at, it may also be useful to set up database Views in the SQL Server to do some of the heavy lifting on the server rather than on the client.
I don't know how well it will do with really large tables, but Visual Studio is much quicker than SQL Management Studio for basic table operations. Open up your database in Server Explorer, right-click on a table, and select either "Open" to just display the data or "New Query" to filter, sort, etc.
I've used Visual Studio to do lots of stuff, just for convenience rather than having to log into the server and work on the database manager directly.
However, have you tried Toad for MS SQL (from Quest Software)? I use it all the time for Oracle, and have had good results (often better than Oracle's tools).
Editing raw data is a dangerous no-no. Better to identify the situations where you find yourself doing that and put together an application interface to act as an intermediary that can prevent you from doing stupid things like breaking a foreign key.
I don't know what the performance would be like for large datasets, but open office has a database program (Base), which is an Access clone and may just be what you are looking for.
You might want to read
Tony Toews's Access Performance FAQ, which provides a number of hints on how to improve performance in an Access application. Perhaps one of those tips will solve the problem in your A2K7 app.

Resources