I'm querying a varchar column that contains all valid datetimes. In the query, I cast the column to datetime.
Keep in mind, changing the column's datatype definition to datetime is not an option. Just trust me, it's not an option.
Through query analysis, I see that the query would be much faster if I could add an index on this column. But it's varchar. If I added an index, it would index based on it's varchar value, right? But I'd want it to index on the datetime value, yes?
Is there anything I can do here for an index?
Valid data is the first priority, because any approach that converts the data to DATETIME will return a value of January 1, 1900 at midnight when the value doesn't match an accepted format.
SQL Server doesn't have function based indexes, so your options are:
A computed column, assuming you can use ALTER TABLE statements to add columns to the table. You could index this column after that.
An indexed view (AKA materialized view), assuming your data meets the requirements
A staging table, cloned from the original (and tweaked if you like) where you import data from the existing table so you can index and manipulate it
Have you considered building an indexed view on top of these generated tables? You could define your varchar-to-datetime conversion in the view, and then index that resulting column.
See Improving Performance with SQL Server 2005 Indexed Views for more information. I'm not an expert on using indexed views, I've only read about them. So I'll leave it up to you to figure out if it will be the right solution in your case.
Related
How do I change a varchar data type to a DATE for the column datatype in a table?
Tried the following:
ALTER TABLE table.name.here MODIFY COLUMN insert_dt DATE;
I just get
SQL compilation error: cannot change column INSERT_DT from type VARCHAR(16777216) to DATE
Unfortunately this sort of data type change is not allowed, generally your best option is to
Add a new column with a temp name, with the new data type
Run an update statement to set the new column to the old column's value (with any required transformations)
Rename the columns, and drop the old column if desired.
It is also sometimes easiest to do this change in a clone or CTAS table and then do an ALTER TABLE SWAP WITH.
Note that a full table update like this does mean recreating micro-partitions, which is generally ok (if a little slow), but you may want to keep an eye on if this affects your clustering. This is easier to control in a CTAS approach because you can explicitly maintain the ordering in an ORDER BY clause.
I have a 55Gb Fact table where I have to delete some records which later on can be reverted back. Number of deleted records vary between 10 to 100 thousand.
Currently my delete strategy is based on this:
I update the dateKey for the records to be deleted e.g. from positive int 20080122 to negative int -20080122 so that current date filters don't include it.
My thinking here is that instead of moving data out and back in the fact table I make the date out of filter date range and then move it back into filterable date range by use of updates on dateKey.
I would like to hear your views on this delete strategy especially around NCI (non clustered index) behavior. Do you think updating the indexed dateKey is better than moving actual data?
Rather than re-purpose the dateKey column, our standard practice is to add a "soft delete" column to the table, either an "is_deleted" bit column or a "deleted_on" datetime column and use that column to filter out "deleted" rows.
This requires more work on your part as all of your existing queries will have to be modified to use this new column, but now your database doesn't have to do the work of re-indexing or deleting/inserting actual data.
I have the following columns in the same table say Authentication
Password_Date (DATETIME, NOT NULL)
Password_Period (INT, FOREIGN KEY of a look-up table)
Password_Cycle (DATETIME, NOT NULL)
The Password_Date will store the datetimewhen the user changes password.
The Password_Period is a foreign key column which is referred from a look-up table. (Say its value is 30)
For the Password_Cyclecolumn, I want to add a formula in computed column.
The formula's logic is to add 30 days(Password_Period) with Password_Date column.
I tried the formula ([Password_Date]+[Password_Period]) in design view but the data type property for Password_Cycle went blank.
Please provide possible solution(s) to get this work.
NOTE: I must use a computed column formula only and not functions or procedures.
It goes blank in the SSMS UI because SQL Server works out the datatype itself for computed columns from the expression. This isn't something defined in the designer.
It will be datetime though I don't like the datetime+int syntax and would recommend DATEADD(DAY, Password_Period, Password_Date) instead.
In computed columns data types goes blank. If u want to use it later You can always cast it for desired type.
basically what I want is when i fill dataset executing some query, all data column must be string only irrespective of type in database tables. Is it possible?
I want to know if any short SQL syntax exists instead of casting every columns when you have huge number of columns or even dynamic number of columns
No, this isn't possible. If you select data from a table the data has the datatype of the column as defined.
You can create a table with only nvarchar fields instead.
No. The database assumes that you defined your columns with a given type because you wanted them to be that type. That's how the data was given to it to store, so that's how it's going to return it. If you don't want them to be that type, the database requires you to explicitly state that.
In terms of performance and optimizations:
When constructing a table in SQL Server, does it matter what order I put the columns in?
Does it matter if my primary key is the first column?
When constructing a multi-field index, does it matter if the columns are adjacent?
Using ALTER TABLE syntax, is it possible to specify in what position I want to add a column?
If not, how can I move a column to a difference position?
In SQL Server 2005, placement of nullable variable length columns has a space impact - placing nullable variable size columns at the end of the definition can result in less space consumption.
SQL Server 2008 adds the "SPARSE" column feature which negates this difference.
See here.
I would say the answer to all those questions is NO, altough my experience with MS-SQL goes as far as SQL2000. Might be a different story in SQL2005
For the fourth bullet: No you can't specify where you want to add the column. Here is the syntax for ALTER TABLE: https://msdn.microsoft.com/en-us/library/ms190273.aspx
In MySQL they offer an ALTER TABLE ADD ... AFTER ... but this doesn't appear in T-SQL.
If you want to reorder the columns you'll have to rebuild the table.
Edit: For your last last bullet point, you'll have to DROP the table and recreate it to reorder the columns. Some graphical tools that manipulate SQL databases will do this for you and make it look like you're reordering columns, so you might want to look into that.
No to the first 3 because the index will hold the data and no the last once also
Column order does not matter while creating a table. We can arrange the columns while retrieving the data from the database. Primary key can be set to any column or combination of columns.
For the first bullet:
Yes, column order does matter, at least if you are using the deprecated BLOBs image, text, or ntext, and using SQL Server <= 2005.
In those cases, you should have those columns at the 'end' of the table, and there is a performance hit every time you retrieve one.
If you're retrieving the data from such a table using a DAL, this is the perfect place for the Lazy Load pattern.