I know, that this type of indexes exist in Oracle. Old versions on MySQL can not create function-based indexes (thanks, google). And new versions? How about PostgreSQL, SQL Server etc?
I don't know inner details of oracle's, but postgres can create index on expression, which can be a function, from :
An index field can be an expression
computed from the values of one or
more columns of the table row. This
feature can be used to obtain fast
access to data based on some
transformation of the basic data. For
example, an index computed on
upper(col) would allow the clause
WHERE upper(col) = 'JIM' to use an
index.
EDIT:
MySQL seems to still be forging this, see virtual columns for details. Also some discussions here. Don't seem very active.
DB2 does it.
MS SQL can not do it, but using computed columns you can have similar effects; see discussion.
PostgreSQL can create indexes on expressions including functions: Indexes on Expressions
You could emulate function based indexes if your database supports insert and update triggers.
Add a column that will contain the function values and add index for that column. Then have your triggers to update column containing function values. Your queries have to change, replace function(params) with function_col.
Related
I am working on a Spring project which uses PostgreSQL and Liquibase. I need to add a unique constraint to a specific column in a table. The table already has a lot of entries and some of them violate the new unique constraint.
Since the application is in production, dropping the table is not an option. I need to implement some sort of modification to the data in the column, so that duplicates get indexed (e.g. we have 2 entries with the value 'foo', after the operation these entries should look something like 'foo' and 'foo2').
So far I've only implemented the change which adds the unique constraint, but I have yet to implement this modification. Is there any functionality in either PostgreSQL or Liquibase which might address this issue?
You need to create an SQL UPDATE query (or queries) that will modify the database and implement the logic that updates duplicates and sets unique values to them.
Then use change type sql in liquibase to instruct liquibase to run that query.
What are the relative merits of each? Both seem to limit the number of rows and columns through which your query needs to trawl, so what determines the basis for choosing one over the other?
An indexed view
can include columns based on an expression.
can include joins of multiple tables.
can be referenced directly in user SQL statements.
allows all deterministic expressions
has complicated prerequisites, but is simple and consistent to use (select * from [indexedview])
A filtered index
is limited to the columns contained within the table.
only allows simple expressions for the filter.
is simple to implement, but the optimizer will determine if usage is appropriate when the base table is queried.
Neither of them can use non-deterministic expressions.
Index View :
i) I have to get result from more than one table.
ii) I create Index on this view to boost performance.
Filtered Index :
i) There are lot of record in single table.
ii) A particular where condition with specific value contain lot of records. and this condition will be very frequently use.Or this condition will be use in very important query where performance is of utmost importance.
In this case we may create filtered index on table.
Check my answer for example
MS SQL Server 2008 - UPDATE a large database
I need to write a query that update only table not indexes
because I want to update an int field and don't need to 10 huge index to be updated
If the int field is included in any of the index definitions then they will have to be updated too.
SQL Server won't allow the base table to have one value and the indexes another for obvious data integrity reasons.
If the int field is not included in any of the index definitions then only the table will be updated anyway.
You can disable the indexes but to re-enable them involves rebuilding the whole index.
It depends on what you really want to do
Keeping the index consistent with the table data is the Consistency in ACID. This is how SQL Server and ACID-compliant RDBMSes work.
There are cases such as bulk loads where you want to delay this Consistency. So if you have this use case, DROP or DISABLE the indexes.
If you disable the indexes:
they will never be used for any query-
all associated unique and foreign keys etc will be disabled too
they are not maintained
If you DROP them, of course they can't be used either.
After your bulk load is finished, you enable or create the indexes/constraints again.
If this is what you really want then read MSDN:
Disabling Indexes
Guidelines for Disabling Indexes and Constraints
Perhaps Filtered Indexes are what you're looking for.
This is a SQL Server 2008 feature that lets you create an index that only applies to certain values in a column.
I am using SQL Server 2000 and I have two databases that both replicate (transactional push subscription) to a single database. I need to know which database the records came from.
So I want to add a fixed column specified in the publication to my table so I can tell which database the row originated from.
How do I go about doing this?
I would like to avoid altering the main databases mostly due to the fact there are many tables I would need to do this to. I was hoping for some built in feature of replication that would do this for me some where. Other than that I would go with the view idea.
You could use a calculated column Use the following on the two databases:
ALTER TABLE TableName ADD
MyColumn AS 'Server1'
Then just define the single "master" database to use a VARCHAR column (or whatever you want) that you fill using the calculated columns value.
You can create a view, which adds the "constant" column, and use it as a replication source.
So the solution for me was to set up the replication publications to allow transformations and create a DTS package for each site that appends the siteid into the tables to keep the ids unique as I can't use guids.
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.