The tspan element's fill attribute is a presentation attribute which is a styling property. When you leave the tspan element, style settings fall back to the settings prior to entering the tspan.
The tspan element's x/y/dx/dy attributes are used to update the current text position. You would not want the current text position to fall back to its setting prior to entering the tspan. If it did then the x position would also reset causing the text following the tspan to horizontally overlap the text in tspan element.
The SVG specifications include a baseline-shift attribute which is designed to handle subscripts and superscripts. This is a presentation attribute and thus only affects the tspan like you want. This attribute can have values of "sub", "super", number, percent. For example
<svg>
<text x="50" y="50">1<tspan baseline-shift="sub" fill="red">2</tspan>3</text>
</svg>
The baseline-shift attribute works in Chrome. Unfortunately, IE does not currently support the baseline-shift attribute.
https://msdn.microsoft.com/en-us/library/gg558060(v=vs.85).aspx
To get the subscript to work in all browsers, it unfortunately looks like you have to use the cumbersome approach of using a second tspan around the 3 that you where trying to avoid.