Improving overall performance on a MS SQL 2008 DB - sql-server-2008

I've been tasked with optimizing a somewhat small Microsoft SQL Server 2008 DB that we all feel is under-performing for its size and whose structure is know to have been abused over the years. Now I'm no dedicated DBA, but I do have enough SQL knowledge to CRUD my way through most problems I've so far encountered so I'm looking for advice here that may fill in some gaps in my knowledge.
1) So my first step will be to take a look at the indexing and the fragmentation thereof. One question is, should I rebuild/reorganize existing indexes or should I drop and recreate them?
My next step would be then be to determine if current keys are indexed and if not, create indexes for them.
2) I've noticed many tables contain columns with foreign key values, but very few contain foreign key constraints on these values. Now I know foreign key constraints aim to maintain the relationships between tables, but should every column containing foreign key values have a foreign key constraint? I feel values used in joins for example, should be constrained so those I will be adding without question wherever I find they're missing. I've read adding foreign key constraints doesn't necessarily improve performance as it results in an extra check during write operations, but indexing these added foreign keys may. What are your thoughts on this?
I'm also researching into adding a maintenance plan that could automatically do index maintenance from time to time and have found some great material to help me accomplish this.
Thanks guys!

Related

Design of MySqlDb (v 8.0): What are the possible sacrifices I make when I decide not to put "Not null" constraint on a foreign key in the table?

I have a question related to this already answered question regards to MySql DB design. I was wondering what are the possible problems/sacrifices related to a decision not to put a "Not Null" constraint on foreign keys in the table? (As mentioned in the linked question, I can have multiple foreign keys in one table and I do not have to always know all of them when uploading data)
Here is an example (simplified):
There are three tables in my DB:
Company
Investor
Investment
Investment table has among others following columns:
Company FK
Investor FK
Problem:
I wanted to know what will be the consequences for the end user, f.e. data analyst, when I will allow "Null value" for Investor FK.
Therefore I think, my question was best answered by Vojta F who showed me both pros and cons of my solution from a perspective of a DB user.
As a DB user (i.e. not a DB admin) I think it is perfectly fine to omit a not null constraint from a foreign key if you don't know its value upon upload. The effect of such an omission is two-fold:
positive: it will be easier for you to upload new data - you won't be forced to insert a fkey value which I think is fine as long as you are aware of this when joining on this column ,
negative: weaker data integrity: it will be harder to resolve records among multiple tables and you'll have to think about the nulls when joining.
In general the gain for using NULL when you need it exceeds any performance, etc, loss (or even gain).
The space consumed so small as to be not worth computing.
The speed considerations are usually non-existent. The Optimizer does a few things differently depending on the NULLability of a indexed column. But, again, your benefit of having (or not having) NULL is likely to exceed any downside.
There are a small number of restrictions. A PRIMARY KEY must include NOT NULL column(s).

SQL - (Foreign key?) constraint to table names?

I'm curious if something like this is possible, if at all reasonable.
I have a column in a table, that's called ref_table and it points to a table that the current entry relates to. Let's say, in table table_people, Person ID 1 is a client and Person ID 3 is an employee, so respectively their ref_tables will show "table_clients" and "table_emplyees". I shouldn't have a problem keeping the values valid through PHP, but what would some ways of achieving it through SQL be?
I tried testing it with a foreign key constraint to INFROMATION_SCHEMA:
FOREIGN KEY `people_constraint_tables` (`ref_table`)
REFERENCES `INFORMATION_SCHEMA`.`COLUMNS`(`COLUMN_NAME`)
ON DELETE RESTRICT
ON UPDATE RESTRICT
No point refining it since it didn't work. It seems like there's one way to make it work but it is a dirty cheat apparently.
Would you do it with triggers? Would you do it at all? Someone with experience with MySQL tell me if that'sreasonable at all, I'd like to know. Thank you.
MySQL doesn't have the facility to do this easily. Other databases do, through generated columns or table inheritance.
Would I do this with triggers? Well, yes and no. If I had to do this with one table and I had to use MySQL and I wanted to introduce relational integrity, then triggers are the way to go. There is little other choice.
But really, I would simply have a different table for each reference type. There is a little bit of overhead in this (in terms of partially filled tables). And for some applications, a single reference table is quite convenient (internationalization comes to mind). But in general, I would stick with the standard method of a separate table for each entity with properly declared foreign key relationships.

Foreign keys when cascades aren't needed

If I don't need to use cascade/restrict and similar constraints in a field which would logically be a foreign key, do I have any reason to explicitly declare it as a foreign key, other than aesthetics?
Wouldn't it actually decrease performance, since it has to test for integrity?
edit: to clarify, I don't need it since:
I won't edit nor delete those values anyway, so I don't need to do cascade and similar checks
Before calling INSERT, I'll check anyway if the target key exists, so I don't need restrict checks either
I understand that this kind of constraint will ensure that that relation will be still valid if the database becomes somehow corrupted, and that is a good thing. However, I'm wondering if there is any other reason to use this function in my case. Am I missing something?
The answers to this quesiton might actually also apply to your question.
If you have columns in tables which reference rows in other tables, you should always be using foreign keys, since even if you think that you 'do not need' the features offered by those checks, it will still help guarantee data integrity in case you forgot a check in your own code.
The performance impact of foreign key checks is neglegible in most cases (see above link), since relational databases use very optimised algorithms to perform them (after all, they are a key feature since they are what actually defines relations between entities).
Another major advantage of FKs is that they will also help others to understand the layout of your database.
Edit:
Since the question linked above is referring to SQL-Server, here's one with replies of a very similar kind for MySQL: Does introducing foreign keys to MySQL reduce performance
You must to do it. If it will touch performance in write -- it's a "pixel" problem.
Main performance problems are in read -- FKs could help query optimizer to select best plan and etc. Even if you DBMS(-s) (if you provide cross-DBMS solution) will gain from it now -- it can happen later.
So answer is -- yes, it's not only aestetics.

Avoiding trouble with foreign key relationships in MySQL

I met Rasmus Lerdorf at a conference a few months ago. During his talk, one suggestion he made was that we rarely use foreign keys, because if something goes wrong with a foreign key relationship it can lock up your whole database.
Here's what foreign keys enforce that Rasmus warned against: "When one table has a foreign key to another table, the concept of referential integrity states that you may not add a record to the table that contains the foreign key unless there is a corresponding record in the linked table."
On the flip side, foreign keys are great for documentation, staying organized and establishing relationships that save coding leg work.
What can be done to mitigate the risks of foreign keys, while leveraging the benefits?
This question / answer does a great job of laying out both the benefits and risks of foreign keys, but I'm looking for more specific insight on how to avoid the pitfalls yet take advantage of the good.
The database wont lock up, its the badly written application on top of it.
Ofcourse you can take some shortcuts when building application but later on you are more likely than not pull the hair on that inconsistent data you have because of not using FKs.

Are Multi-column Primary Keys in MySQL a optimisation problem?

Been looking into using multi-column primary keys and as performance is extremely important with the size of traffic and database I need to know if there is anything to consider before I start throwing out the unique ID method on many of my tables and start using mulit column primary keys.
So, what are the performance/optimisation pros/cons to using multi column primary keys versus a basic single column, auto-inc primary key?
Is there a particular reason that you need/want to use multi-column keys instead of an (I assume) already created single-column key?
One of the problems with Natural Keys is dealing with cascading an update to the key value across all the foreign keys. A surrogate key such as an auto-increment column avoids this.
In terms of performance, depending on the row count, the data types of the columns, your storage engine, and the amount of RAM you have dedicated to MySQL, multi-column keys can affect performance due to the sheer size of the index.
In my experience, it is almost always easier in terms of development and maintenance to use a surrogate key as the PK and then create indexes that cover your queries across the natural keys. However, the only way to determine the true performance impact for your application is to benchmark it with realistic a realistic load and dataset.
HTH -
Chris
I wouldn't think that there would be any performance problems with multiple primary keys. It's more or less equivalent to having multiple indexes (you will spend a little bit more time computing index values when doing inserts).
Sometimes the data model makes more sense with multiple keys. I'd worry about being straightforward first and worry about performance second. You can always add more indexes, improve your queries, or twiddle server settings.
I think the most I've encountered was a 4-column primary key. Makes me cringe a little bit, but it worked¹.
[1] "worked" is defined to mean "the application performed to specification", and is not meant to imply that actual tasks were accomplished using said application. :)