From cddfc7fd9259f11eaebbb5558ff3bed8498aeb29 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Thu, 15 Sep 2022 14:25:36 -0700 Subject: [PATCH] table designer perf improvement - add user setting for preload db model (#20608) * add user setting for preload db model * vbump sts * more description --- extensions/mssql/config.json | 2 +- extensions/mssql/package.json | 5 ++++ extensions/mssql/package.nls.json | 3 ++- .../mssql/src/tableDesigner/tableDesigner.ts | 27 +++++++++++++++++++ extensions/mssql/src/utils.ts | 17 ++++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/extensions/mssql/config.json b/extensions/mssql/config.json index b13c01fb40..9ff8dae56f 100644 --- a/extensions/mssql/config.json +++ b/extensions/mssql/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "4.3.0.18", + "version": "4.3.0.23", "downloadFileNames": { "Windows_86": "win-x86-net6.0.zip", "Windows_64": "win-x64-net6.0.zip", diff --git a/extensions/mssql/package.json b/extensions/mssql/package.json index cb62206bd4..b954b9c8bc 100644 --- a/extensions/mssql/package.json +++ b/extensions/mssql/package.json @@ -393,6 +393,11 @@ "type": "boolean", "description": "%mssql.parallelMessageProcessing%", "default": false + }, + "mssql.tableDesigner.preloadDatabaseModel": { + "type": "boolean", + "default": false, + "description": "%mssql.tableDesigner.preloadDatabaseModel%" } } }, diff --git a/extensions/mssql/package.nls.json b/extensions/mssql/package.nls.json index eb81ca21b3..91e45eedaa 100644 --- a/extensions/mssql/package.nls.json +++ b/extensions/mssql/package.nls.json @@ -188,5 +188,6 @@ "title.newTable": "New Table", "title.designTable": "Design", - "mssql.parallelMessageProcessing" : "[Experimental] Whether the requests to the SQL Tools Service should be handled in parallel. This is introduced to discover the issues there might be when handling all requests in parallel. The default value is false. Relaunch of ADS is required when the value is changed." + "mssql.parallelMessageProcessing" : "[Experimental] Whether the requests to the SQL Tools Service should be handled in parallel. This is introduced to discover the issues there might be when handling all requests in parallel. The default value is false. Relaunch of ADS is required when the value is changed.", + "mssql.tableDesigner.preloadDatabaseModel": "Whether to preload the database model when the database node in the object explorer is expanded. When enabled, the loading time of table designer can be reduced. Note: You might see higher than normal memory usage if you need to expand a lot of database nodes." } diff --git a/extensions/mssql/src/tableDesigner/tableDesigner.ts b/extensions/mssql/src/tableDesigner/tableDesigner.ts index 7d5fa92e23..acff110885 100644 --- a/extensions/mssql/src/tableDesigner/tableDesigner.ts +++ b/extensions/mssql/src/tableDesigner/tableDesigner.ts @@ -10,11 +10,15 @@ import { sqlProviderName } from '../constants'; import { generateUuid } from 'vscode-languageclient/lib/utils/uuid'; import { ITelemetryEventProperties, Telemetry } from '../telemetry'; import * as nls from 'vscode-nls'; +import { getConfigPreloadDatabaseModel, setConfigPreloadDatabaseModel } from '../utils'; const localize = nls.loadMessageBundle(); const NewTableText = localize('tableDesigner.NewTable', "New Table"); +const DidInformUserKey: string = 'tableDesigner.DidInformUser'; + export function registerTableDesignerCommands(appContext: AppContext) { appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.newTable', async (context: azdata.ObjectExplorerContext) => { + void showPreloadDbModelSettingPrompt(appContext); const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true); const tableIcon = context.nodeInfo.nodeSubType as azdata.designers.TableIcon; const telemetryInfo = await getTelemetryInfo(context, tableIcon); @@ -32,6 +36,7 @@ export function registerTableDesignerCommands(appContext: AppContext) { })); appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.designTable', async (context: azdata.ObjectExplorerContext) => { + void showPreloadDbModelSettingPrompt(appContext); const server = context.connectionProfile.serverName; const database = context.connectionProfile.databaseName; const schema = context.nodeInfo.metadata.schema; @@ -62,3 +67,25 @@ async function getTelemetryInfo(context: azdata.ObjectExplorerContext, tableType telemetryInfo['tableType'] = tableType; return telemetryInfo; } + +async function showPreloadDbModelSettingPrompt(appContext: AppContext): Promise { + // skip if the setting is already enabled. + if (getConfigPreloadDatabaseModel()) { + return; + } + + // only show the prompt once. + const didInformUser = appContext.extensionContext.globalState.get(DidInformUserKey); + if (!didInformUser) { + void appContext.extensionContext.globalState.update(DidInformUserKey, true); + } else { + return; + } + const yesOption = localize('tableDesigner.yes', "Yes"); + const noOption = localize('tableDesigner.no', "No"); + + const result = await vscode.window.showInformationMessage(localize('tableDesigner.turnOnPreloadingMessage', "Do you want to reduce the table designer load time by enabling the database model preloading? The database model will be preloaded when you expand the database node in object explorer."), yesOption, noOption); + if (result === yesOption) { + setConfigPreloadDatabaseModel(true); + } +} diff --git a/extensions/mssql/src/utils.ts b/extensions/mssql/src/utils.ts index 2b176231fc..e5071ece2a 100644 --- a/extensions/mssql/src/utils.ts +++ b/extensions/mssql/src/utils.ts @@ -21,6 +21,7 @@ const configLogFilesRemovalLimit = 'logFilesRemovalLimit'; const extensionConfigSectionName = 'mssql'; const configLogDebugInfo = 'logDebugInfo'; const parallelMessageProcessingConfig = 'parallelMessageProcessing'; +const tableDesignerPreloadConfig = 'tableDesigner.preloadDatabaseModel'; /** * @@ -93,6 +94,22 @@ export function getConfigTracingLevel(): string { } } +export function getConfigPreloadDatabaseModel(): boolean { + let config = getConfiguration(); + if (config) { + return config.get(tableDesignerPreloadConfig); + } else { + return false; + } +} + +export function setConfigPreloadDatabaseModel(enable: boolean): void { + let config = getConfiguration(); + if (config) { + void config.update(tableDesignerPreloadConfig, enable, true); + } +} + export async function getParallelMessageProcessingConfig(): Promise { const config = getConfiguration(); if (!config) {