0

Im building a system using SQL Server 2012, it's a web app containing same data type but its specifical for each user, so we are using one database per user, every single database has the same structure and it's created dinamically and live when the user clicks on the confirm account email.

The problem is the script that creates the databases is restoring a database called DB_GENERIC.bak and its taking more time than i would expect. Im looking for ways to optimize this, and end up with a brand new database created but reducing the time it takes. (right now is using like 15 seconds to create the database), and the Generic database its restoring its small (aprox 5mb, and 600kb compressed) and all the tables are empty.

Is there any other way of accomplishing this instead of restoring a full database backup? can i script the whole generic database on t-sql and execute that changing the database name? is it going to be any faster? Or is it any other way of compressing or generating a less resource-consumer backup, the thing is that i dont need data or anything, just tables, procedures, functions, and schemas.

Thanks in advance


UDPATE:

Thanks to everyone that replied to my question, the answers were all great and helpful. I ended up using @Love2Learn answer and i tried that detach-copy-attach method.

Just for you to imagine how this was implemented, i had an store procedure that's the one in charge of copying-attaching the new database from a database template that has the following:

--executing bat that copies the database-1-template.mdf and database-2-template.mdf (as well as log files) to the DATA folder in my sql instance
--and renames them (then they'll be attached)
DECLARE @BATCopy VARCHAR(MAX) = 'C:\helpers\copyMDFAndLogFiles.bat'

--building command for xp_cmdshell with parameters (new databases names)
DECLARE @command varchar(500) = @BATCopy + ' ' + @database1Name + ' ' + @database2Name

--PRINT @command

EXEC xp_cmdshell @command, no_output

--attaching new databases
SET @SQL = ' USE [master] 
CREATE DATABASE ' + @database1Name + '
    ON (FILENAME = ''' + @SQLDATAPath + @database1Name + '.mdf''), 
    (FILENAME = ''' + @SQLDATAPath + @database1Name + '_log.ldf'') 
    FOR ATTACH; 

CREATE DATABASE ' + @database2Name+ '
    ON (FILENAME = ''' + @SQLDATAPath + @database2Name+ '.mdf''), 
    (FILENAME = ''' + @SQLDATAPath+ @database2Name+ '_log.ldf'') 
    FOR ATTACH;'

EXECUTE(@SQL)

--renaming logical files

SET @SQL = '
ALTER DATABASE '+@database1Name +'
MODIFY FILE (NAME = Database1_Generic, NEWNAME = '+@database1Name +')

ALTER DATABASE '+@database1Name +'
MODIFY FILE (NAME = Database1_Generic_Log, NEWNAME = '+@database1Name +'_log)

ALTER DATABASE '+@database2Name+'
MODIFY FILE (NAME = Database2_Generic, NEWNAME = '+@database2Name+')

ALTER DATABASE '+@database2Name+'
MODIFY FILE (NAME = Database2_Generic_Log, NEWNAME = '+@database2Name+'_log)
'

EXECUTE (@SQL)

I hope this helps anyone that needs to do the same thing i needed to do, and thanks you all for your answers.

Julian.

Julian
  • 171
  • 2
  • 10
  • Have you thought about scalability? Is there a really good reason to have a database per user? You will likely not be able to take advantage of connection pooling. – Jay Walker Mar 06 '13 at 15:12
  • @JayWalker The decision about creating a database per user was not mine, so there must be a reason but im not absolutely sure why. The idea was to have as much databases as the server could handle (and kee stable), and if more databases were needed then a new server would be added to the system. – Julian Mar 26 '13 at 19:09

3 Answers3

0

Look at this answer... Best way to copy a database (SQL Server 2008)

The best way is detach-copy-attach. You would want to create a template database and use this as your base for each new database.

Community
  • 1
  • 1
Eric J. Price
  • 2,740
  • 1
  • 15
  • 21
  • You are totally right, i didnt think of that alternative, currently im restoring a .bak of the template database. I will script an attach and try with that, should be faster than restoring the .bak. Thanks :) – Julian Mar 26 '13 at 18:43
  • Sorry about taking so long to answer, Stackoverflow seems to not have delivered me any notifications about new answers to my question. – Julian Mar 26 '13 at 19:12
  • 1
    @Julian Heh, it's all good, let us know if the implementation works for you. If it does, accepting the answer and upvoting is a good way to make it obvious to people that find your question in a search which option you found helpful. – Eric J. Price Mar 26 '13 at 19:13
  • Hey! I tried and it worked as a charm! It's taking abour 2 sec to copy-attach the database (i don't have to detach it since the template is already detached). Thanks for your help! – Julian Mar 27 '13 at 13:45
0

...the thing is that i dont need data or anything, just tables, procedures, functions, and schemas.

Step 1 is to split your schema from your data. Use SSMS "Script Database As..." to generate an SQL Script that contains only schema/data you want a new database to have. Make a plan for future schema mods ("basedatabase.sql", "patch01.sql", etc.) because it's going to happen and you're going to have to apply those mods to a lot of databases.

Once you've gotten rid of the data, creating the database from a script will be a lot faster. If that isn't fast enough, back up the empty DB and restore to a new database from that. (SQL Server Azure has a nice CREATE DATABASE_B AS COPY OF DATABASE_A but that is not in regular SQL Server.)

BTW I agree with other posters re: wisdom of multiple databases; if you expect to have 50 customers, this is fine. If you expect to have 10,000 customers you'd be better served by a different approach.

Robert Calhoun
  • 4,823
  • 1
  • 38
  • 34
  • The scripting option was put aside at first because the process of scripting the database each time would be a little bit annoying. Im currently backuping a template and restoring that template for each new account. I'll try the detach-copy-attach that suggested me above, but if that doesnt work i'll probably end up using an script. Regarding the "wisdom of multiple databases", it was done expecting around 100-150 DB, and if there were more, then a new server would be added to the system. It was not my decision, so im a little "forced" to do that, and the system refactor would be big. – Julian Mar 26 '13 at 19:06
  • Sorry about taking so long to answer, Stackoverflow seems to not have delivered me any notifications about new answers to my question. – Julian Mar 26 '13 at 19:11
  • Restore from a backup is certainly faster than a generating a new database from a script. I am just suggesting dumping the schema as a script and re-importing so that your "golden master" database contains only the schema. You should be fine with 150 databases per server; SQL Server supports 32,768 databases per instance or something like that. – Robert Calhoun Mar 27 '13 at 02:18
0

My belief is that you'll be best of by scripting the database and executing the script. This has the advantage that you can easily version the content. Also, for upgrading all tenant databases to a new version you need to script out the delta anyway.

You can create the initial script using the script database wizard. Be sure to change the advanced options because they have crazy defaults. They will just leave out some things like triggers and others.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Hi, scripting the database was an option, but we let it aside for a while because of "lazyness" regarding to script the database each time and check that the script went well and all. Having a "full copy" of the database and just having to change the logins to that db seemed faster and easier to maintain (like deploying a new version of the db for new accounts would be as simple as performing a template-backup). I will check out the answer above that said detach-copy-attach, if that does not go well, i'll end up scripting i think. Thanks for answering! – Julian Mar 26 '13 at 19:00
  • Sorry about taking so long to answer, Stackoverflow seems to not have delivered me any notifications about new answers to my question. – Julian Mar 26 '13 at 19:11
  • Thanks for reporting back on this interesting question! I'd like to find out how the different strategies proposed here turned out. So feel free to leaver further comments :) – usr Mar 26 '13 at 19:21
  • I just updated my question with the final result. thanks for your help. – Julian Mar 27 '13 at 13:59