As near as I can tell, the performance problem is actually in the implementation of Resolve-Path in the SqlServer psprovider. Resolve-Path is how the default implementation of TabExpansion (in Powershell v2) does path completion.
I was able to work around this problem by overriding the TabExpansion function to use Get-ChildItem and Where-Object instead of Resolve-Path. You can find the latest implementation in this bitbucket repo.
Here's the current implementation:
function TabExpansion($line, $lastWord) {
if (!((get-location).Provider.Name -eq "SqlServer")) {
TabExpansionSqlPsBackup $line $lastWord
}
else {
$index = $lastWord.LastIndexOfAny(@('\', '/'))
if ($index -gt -1) {
$parent = $lastWord.substring(0, $index+1)
$leaf = $lastWord.substring($index+1)
}
else {
$parent = ""
$leaf = $lastWord
}
$matches = ls -path $parent | ?{ $_.PSChildName -match "^$leaf" }
if ($matches) {
$matches | %{ $parent + $_.PSChildName }
}
else {$lastWord}
}
}
Put that function in the sqlps profile file located at ~\Documents\WindowsPowerShell\Microsoft.SqlServer.Management.PowerShell.sqlps_profile.ps1